mirror of
https://github.com/valitydev/yamerl.git
synced 2024-11-06 02:45:23 +00:00
parent
1f39cf3455
commit
c19aab0228
6
.gitignore
vendored
6
.gitignore
vendored
@ -7,8 +7,4 @@
|
|||||||
/doc/
|
/doc/
|
||||||
/ebin
|
/ebin
|
||||||
/rebar.lock
|
/rebar.lock
|
||||||
|
/rebar3.crashdump
|
||||||
# Elixir Support
|
|
||||||
/mix.lock
|
|
||||||
/yamerl-*-contents.tar.gz
|
|
||||||
*.ez
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
# yamerl Documentation
|
|
||||||
|
|
||||||
* [Features](features.md#yamerl-features)
|
|
||||||
* [Installation instructions](installation.md#yamerl-installation)
|
|
||||||
* [Reference Manual](reference-manual#yamerl-reference-manual)
|
|
||||||
* [User Guide](user-guide#yamerl-user-guide)
|
|
||||||
* [Alternatives to yamerl](alternatives.md#alternatives-to-yamerl)
|
|
@ -1,15 +0,0 @@
|
|||||||
# Alternatives to yamerl
|
|
||||||
|
|
||||||
## YAML parsers
|
|
||||||
|
|
||||||
* [yamler](https://github.com/goertzenator/yamler):
|
|
||||||
* Based on libyaml, wrapped in a NIF
|
|
||||||
* Support YAML 1.1
|
|
||||||
* Faster than yamerl
|
|
||||||
* Support Erlang atoms, however, single-quoted scalar are treated as atom, which breaks the YAML specifications
|
|
||||||
* Don't support Erlang fun()
|
|
||||||
|
|
||||||
## JSON parsers
|
|
||||||
|
|
||||||
* `mochijson2`, provided by [Mochiweb](https://github.com/mochi/mochiweb):
|
|
||||||
* A lot faster than yamerl
|
|
@ -1,77 +0,0 @@
|
|||||||
# Features
|
|
||||||
|
|
||||||
## When to use or not yamerl
|
|
||||||
|
|
||||||
### Advantages
|
|
||||||
|
|
||||||
* Pure Erlang implementation:
|
|
||||||
* should scale more easily than a port-driver based implementation;
|
|
||||||
* won't take the whole VM down in case of a crash.
|
|
||||||
* YAML 1.2 support, which is not widely supported in many other languages.
|
|
||||||
|
|
||||||
### Caveats
|
|
||||||
|
|
||||||
* Current implementation is slow, compared to yamler (NIF-based) or any JSON-only parsers.
|
|
||||||
* Adding schemas is not easy.
|
|
||||||
* No support for YAML serialization.
|
|
||||||
|
|
||||||
## Features + examples
|
|
||||||
|
|
||||||
* Support [YAML 1.2](http://www.yaml.org/spec/1.2/spec.html) parsing:
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:string("YAML snippet").
|
|
||||||
```
|
|
||||||
|
|
||||||
* Support [YAML 1.1](http://yaml.org/spec/1.1/) parsing:
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:string("YAML snippet", [{schema, yaml11}]).
|
|
||||||
```
|
|
||||||
|
|
||||||
* Support [JSON](http://json.org/) parsing:
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:string(<<"JSON snippet">>, [{schema, json}]).
|
|
||||||
```
|
|
||||||
|
|
||||||
* Support **Erlang atom** node type, either when tagged as atom, or if autodetected in plain scalars, and, if asked, only if the atom already exists:
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
% Enable support for Erlang atoms.
|
|
||||||
yamerl_app:set_param(node_mods, [yamerl_node_erlang_atom]),
|
|
||||||
yamerl_constr:string("!<tag:yamerl,2012:atom> atom").
|
|
||||||
|
|
||||||
% Autodetect Erlang atoms in plain scalars.
|
|
||||||
yamerl_app:set_param(node_mods, [yamerl_node_erlang_atom]),
|
|
||||||
yamerl_constr:string("atom", [{erlang_atom_autodetection, true}]).
|
|
||||||
|
|
||||||
% Atoms must already exist.
|
|
||||||
yamerl_app:set_param(node_mods, [yamerl_node_erlang_atom]),
|
|
||||||
yamerl_constr:string("atom", [
|
|
||||||
{erlang_atom_autodetection, true},
|
|
||||||
{erlang_atom_only_if_exist, true}
|
|
||||||
]).
|
|
||||||
```
|
|
||||||
|
|
||||||
* Support **Erlang fun()** node type:
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
% Enable support for Erlang fun().
|
|
||||||
yamerl_app:set_param(node_mods, [yamerl_node_erlang_fun]),
|
|
||||||
[Plus_One_Fun] = yamerl_constr:string(<<"!<tag:yamerl,2012:fun> fun(X) -> X + 1 end.">>),
|
|
||||||
|
|
||||||
Plus_One_Fun(2). % Return 3.
|
|
||||||
```
|
|
||||||
|
|
||||||
* Provide a **yamler compatibility layer**:
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
% Both calls return the same value.
|
|
||||||
yaml:load_file("input.yaml", [{schema, yaml_schema_failsafe}]),
|
|
||||||
yamerl_yamler_compat:load_file("input.yaml", [{schema, yaml_schema_failsafe}])
|
|
||||||
```
|
|
||||||
|
|
||||||
## Alternatives to yamerl
|
|
||||||
|
|
||||||
If yamerl doesn't fit your needs, you can read a [list of alternatives](alternatives.md#alternatives-to-yamerl).
|
|
@ -1,176 +0,0 @@
|
|||||||
# Installation
|
|
||||||
|
|
||||||
## tl;dr
|
|
||||||
|
|
||||||
### Using Rebar
|
|
||||||
|
|
||||||
1. Take the sources from GitHub and run rebar(1):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone 'https://github.com/yakaz/yamerl.git'
|
|
||||||
cd yamerl/
|
|
||||||
rebar compile
|
|
||||||
```
|
|
||||||
|
|
||||||
### Using the Autotools
|
|
||||||
|
|
||||||
1. Take the sources from GitHub and generate Autotools files:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone 'https://github.com/yakaz/yamerl.git'
|
|
||||||
cd yamerl/
|
|
||||||
autoreconf -vif
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Enter the sources directory and run the usual configure/make/make
|
|
||||||
install:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./configure
|
|
||||||
make
|
|
||||||
make install
|
|
||||||
```
|
|
||||||
|
|
||||||
The default installation path is your Erlang's distribution libraries
|
|
||||||
directory.
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
### Build dependencies
|
|
||||||
|
|
||||||
If you're using Rebar:
|
|
||||||
* rebar
|
|
||||||
* awk (tested with FreeBSD's awk, mawk and gawk, should work with any
|
|
||||||
flavor of Awk)
|
|
||||||
* Erlang/OTP R14B02 or later
|
|
||||||
|
|
||||||
If you're using the Autotools:
|
|
||||||
* autoconf 2.64 or later
|
|
||||||
* automake 1.11 or later
|
|
||||||
* awk (tested with FreeBSD's awk, mawk and gawk, should work with any
|
|
||||||
flavor of Awk)
|
|
||||||
* make (tested with FreeBSD's make and GNU make, should work with any
|
|
||||||
flavor of make)
|
|
||||||
* Erlang/OTP R14B02 or later
|
|
||||||
|
|
||||||
### Testsuite dependencies
|
|
||||||
|
|
||||||
* Erlang/OTP R14B02 or later
|
|
||||||
* Perl
|
|
||||||
* [yamler](https://github.com/goertzenator/yamler) (optional)
|
|
||||||
|
|
||||||
### Runtime dependencies
|
|
||||||
|
|
||||||
* Erlang/OTP R14B02 or later
|
|
||||||
|
|
||||||
## Building using Rebar
|
|
||||||
|
|
||||||
A single step is required here:
|
|
||||||
```bash
|
|
||||||
rebar compile
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to run the testsuite:
|
|
||||||
```bash
|
|
||||||
rebar eunit
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building using the Autotools
|
|
||||||
|
|
||||||
### Generating the Autotools files
|
|
||||||
|
|
||||||
> If you use a release tarball, you can skip this step.
|
|
||||||
|
|
||||||
You need to generate the Autotools files:
|
|
||||||
* after a fresh clone of the Git repository;
|
|
||||||
* each time you modify `configure.ac` or any `Makefile.am`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
autoreconf -vif
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuring the build
|
|
||||||
|
|
||||||
#### Inside sources vs. outside sources
|
|
||||||
|
|
||||||
* The simplest method is to run the `configure` script from the sources
|
|
||||||
directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./configure
|
|
||||||
```
|
|
||||||
|
|
||||||
* The **recommended method** is to run the `configure` script from a
|
|
||||||
separate directory, in order to keep the sources directory clean:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create and enter a separate directory.
|
|
||||||
mkdir build-yamerl
|
|
||||||
cd build-yamerl
|
|
||||||
|
|
||||||
# Execute the configure script from this directory; all files are
|
|
||||||
# created in this directory, not in the sources directory.
|
|
||||||
/path/to/yamerl-sources/configure
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Changing the install path
|
|
||||||
|
|
||||||
The default installation path is your Erlang's distribution libraries
|
|
||||||
directory, as reported by `code:lib_dir()`. To install in a different
|
|
||||||
directory (eg. because you do not have sufficient privileges), you can
|
|
||||||
use the `--prefix` option:
|
|
||||||
```bash
|
|
||||||
.../configure --prefix=$HOME/my-erlang-apps
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Using a non-default Erlang distribution
|
|
||||||
|
|
||||||
By default, the system Erlang distribution is used by querying `erl(1)`
|
|
||||||
taken from the `$PATH`. You can specify another Erlang distribution:
|
|
||||||
|
|
||||||
* using the `--with-erlang` option to point to the Erlang root directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
.../configure --with-erlang=/erlang/root/directory
|
|
||||||
```
|
|
||||||
|
|
||||||
* using the `$ERL` variable to point to the alternate `erl(1)` binary:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
.../configure ERL=/path/to/erl
|
|
||||||
```
|
|
||||||
|
|
||||||
### Compiling
|
|
||||||
|
|
||||||
Easy peasy Japanesey!
|
|
||||||
```bash
|
|
||||||
make
|
|
||||||
```
|
|
||||||
|
|
||||||
You can use multiple make jobs (ie. using the `-j` option). However
|
|
||||||
Erlang modules are built using Erlang's `make` application. And, as of
|
|
||||||
this writing (Erlang R15B03), this application doesn't build modules in
|
|
||||||
parallel.
|
|
||||||
|
|
||||||
If you want to run the testsuite:
|
|
||||||
```bash
|
|
||||||
make check
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installing
|
|
||||||
|
|
||||||
> Installation is only supported when using the Autotools.
|
|
||||||
|
|
||||||
* Simply run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make install
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that you may need increased privileges.
|
|
||||||
|
|
||||||
* To help mostly packagers, the `$DESTDIR` variable is honored:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make install DESTDIR=/path/to/fake/root
|
|
||||||
```
|
|
@ -1,5 +0,0 @@
|
|||||||
# yamerl Reference Manual
|
|
||||||
|
|
||||||
## Modules
|
|
||||||
|
|
||||||
* [`yamerl_constr`](module-yamerl_constr.md)
|
|
@ -1,274 +0,0 @@
|
|||||||
# Module: yamerl\_constr
|
|
||||||
|
|
||||||
## Functions list
|
|
||||||
|
|
||||||
* In-memory string parsing:
|
|
||||||
* [`string/1`](#function-stringstring)
|
|
||||||
* [`string/2`](#function-stringstring-options)
|
|
||||||
* File parsing:
|
|
||||||
* [`file/1`](#function-filefilename)
|
|
||||||
* [`file/2`](#function-filefilename-options)
|
|
||||||
* Stream parsing:
|
|
||||||
* [`new/1`](#function-newsource)
|
|
||||||
* [`new/2`](#function-newsource-options)
|
|
||||||
* [`next_chunk/2`](#function-next_chunkconstr_state-chunk)
|
|
||||||
* [`next_chunk/3`](#function-next_chunkconstr_state-chunk-last_chunk)
|
|
||||||
* [`last_chunk/2`](#function-last_chunkconstr_state-chunk)
|
|
||||||
|
|
||||||
## Functions reference
|
|
||||||
|
|
||||||
### Function: new(Source)
|
|
||||||
|
|
||||||
Same as:
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:new(Source, []).
|
|
||||||
```
|
|
||||||
|
|
||||||
> See [`new/2`](#function-newsource-options).
|
|
||||||
|
|
||||||
### Function: new(Source, Options)
|
|
||||||
|
|
||||||
#### Arguments
|
|
||||||
|
|
||||||
* `Source`: An arbitrary term describing the source of the data.
|
|
||||||
* `Options`: A proplist of options:
|
|
||||||
* `{detailed_constr, boolean()}`: Flag to enable/disable the detailed construction mode (default: `false`).
|
|
||||||
* `{schema, failsafe | json | core | yaml11}`: Name of the official schema to use (default: `core`).
|
|
||||||
* `{node_mods, Mods_List}`: List of Erlang modules to extend supported node types (default: `[]`).
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
|
|
||||||
Create a new construction state.
|
|
||||||
|
|
||||||
The returned state is then used in the [next\_chunk/2](#function-next_chunkconstr_state-chunk), [next\_chunk/3](#function-next_chunkconstr_state-chunk-last_chunk) and [last\_chunk/2](#function-last_chunkconstr_state-chunk) functions.
|
|
||||||
|
|
||||||
#### Return values & exceptions
|
|
||||||
|
|
||||||
If specified options are valid, return a new construction state.
|
|
||||||
|
|
||||||
If specified options are invalid, throw an exception.
|
|
||||||
|
|
||||||
### Function: next\_chunk(Constr\_State, Chunk)
|
|
||||||
|
|
||||||
Same as:
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:next_chunk(Constr_State, Chunk, false).
|
|
||||||
```
|
|
||||||
|
|
||||||
> See [`next_chunk/3`](#function-next_chunkconstr_state-chunk-last_chunk).
|
|
||||||
|
|
||||||
### Function: next\_chunk(Constr\_State, Chunk, Last\_Chunk)
|
|
||||||
|
|
||||||
#### Arguments
|
|
||||||
|
|
||||||
* `Constr_State`: A construction state as returned by [new/1](#function-newsource), [new/2](#function-newsource-options), [next\_chunk/2](#function-next_chunkconstr_state-chunk) or [next\_chunk/3](#function-next_chunkconstr_state-chunk-last_chunk).
|
|
||||||
* `Chunk`: A UTF-8/16/32-encoded binary chunk of a stream containing one or more YAML documents.
|
|
||||||
* `Last_Chunk`: Flag indicating if the given chunk is the last one or not.
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
|
|
||||||
Parse the given chunk and return a new construction state or, if last chunk, a list of constructed YAML documents.
|
|
||||||
|
|
||||||
The chunk must be an Erlang binary, using the UTF-8, UTF-16 or UTF-32 Unicode encoding. A leading _BOM_ character in the first chunk is used to determine the encoding and endianness. If no BOM is present, UTF-8 is assumed.
|
|
||||||
|
|
||||||
#### Return values & exceptions
|
|
||||||
|
|
||||||
If parsing succeeds and `Last_Chunk` is `false`, return `{continue, New_Constr_State}`. The `New_Constr_State` must be used for subsequent calls to [next\_chunk/2](#function-next_chunkconstr_state-chunk), [next\_chunk/3](#function-next_chunkconstr_state-chunk-last_chunk) or [last\_chunk/2](#function-last_chunkconstr_state-chunk).
|
|
||||||
|
|
||||||
If parsing and construction succeed and `Last_Chunk` is `true`, return a list of documents:
|
|
||||||
* Basic-terms-based documents are returned if option `{detailed_constr, false}` is set (default);
|
|
||||||
* Detailed records-based documents are returned if option `{detailed_constr, true}` is set.
|
|
||||||
|
|
||||||
If parsing or construction fails, throw an exception.
|
|
||||||
|
|
||||||
#### Examples
|
|
||||||
|
|
||||||
##### Parse a valid stream
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
Stream_St1 = yamerl_constr:new({file, "<stdin>"}),
|
|
||||||
{continue, Stream_St2} = yamerl_constr:next_chunk(Stream_St1, <<"He">>),
|
|
||||||
{continue, Stream_St3} = yamerl_constr:next_chunk(Stream_St2, <<"ll">>),
|
|
||||||
yamerl_constr:last_chunk(Stream_St3, <<"o!">>).
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
```erlang
|
|
||||||
% List of documents; here, only one.
|
|
||||||
[
|
|
||||||
% Document root node: a string.
|
|
||||||
"Hello!"
|
|
||||||
].
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Parse an invalid stream
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
Stream_St1 = yamerl_constr:new({file, "<stdin>"}),
|
|
||||||
{continue, Stream_St2} = yamerl_constr:next_chunk(Stream_St1, <<"'He">>),
|
|
||||||
{continue, Stream_St3} = yamerl_constr:next_chunk(Stream_St2, <<"ll">>),
|
|
||||||
yamerl_constr:last_chunk(Stream_St3, <<"o!">>) % Unfinished single-quoted scalar.
|
|
||||||
```
|
|
||||||
|
|
||||||
Throws:
|
|
||||||
```erlang
|
|
||||||
{yamerl_exception,
|
|
||||||
% List of warnings and errors; here, one fatal error.
|
|
||||||
[
|
|
||||||
% Error #1.
|
|
||||||
{yamerl_parsing_error, error,
|
|
||||||
"Unexpected end-of-stream while parsing flow scalar", % Human-readable message.
|
|
||||||
1, 8, % Error location.
|
|
||||||
unexpected_eos,
|
|
||||||
{yamerl_scalar, 1, 1, {yamerl_tag, 1, 1, {non_specific, "!"}}, % Token being parsed.
|
|
||||||
flow, single_quoted,
|
|
||||||
"Hello!"},
|
|
||||||
[]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Function: last\_chunk(Constr\_State, Chunk)
|
|
||||||
|
|
||||||
Same as:
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:next_chunk(Constr_State, Chunk, true).
|
|
||||||
```
|
|
||||||
|
|
||||||
> See [`next_chunk/3`](#function-next_chunkconstr_state-chunk-last_chunk).
|
|
||||||
|
|
||||||
### Function: string(String)
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
|
|
||||||
Same as:
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:string(String, []).
|
|
||||||
```
|
|
||||||
|
|
||||||
> See [`string/2`](#function-stringstring-options).
|
|
||||||
|
|
||||||
### Function: string(String, Options)
|
|
||||||
|
|
||||||
#### Arguments
|
|
||||||
|
|
||||||
* `String`: A string or UTF-8/16/32-encoded binary containing one or more YAML documents.
|
|
||||||
* `Options`: A proplist of options; see [`new/2`](#function-newsource-options).
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
|
|
||||||
Parse the given string and return a list of constructed YAML documents.
|
|
||||||
|
|
||||||
The `String` argument can be:
|
|
||||||
|
|
||||||
* an Erlang string (ie. list):
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:string("This is a string").
|
|
||||||
```
|
|
||||||
|
|
||||||
* a binary using the UTF-8, UTF-16 or UTF-32 Unicode encoding. A leading _BOM_ character is used to determine the encoding and endianness. If no BOM is present, UTF-8 is assumed.
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:string(<<50,32,226,130,172>>). % The string "2 €" encoded in UTF-8.
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Return values & exceptions
|
|
||||||
|
|
||||||
If parsing and construction succeed, return a list of documents:
|
|
||||||
* Basic-terms-based documents are returned if option `{detailed_constr, false}` is set (default);
|
|
||||||
* Detailed records-based documents are returned if option `{detailed_constr, true}` is set.
|
|
||||||
|
|
||||||
If parsing or construction fails, throw an exception.
|
|
||||||
|
|
||||||
#### Examples
|
|
||||||
|
|
||||||
##### Get simple documents
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:string("Hello!").
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
```erlang
|
|
||||||
% List of documents; here, only one.
|
|
||||||
[
|
|
||||||
% Document root node: a string.
|
|
||||||
"Hello!"
|
|
||||||
].
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Get detailed documents
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:string("Hello!", [detailed_constr]).
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
```erlang
|
|
||||||
% List of documents; here, only one.
|
|
||||||
[
|
|
||||||
% Document #1.
|
|
||||||
{yamerl_doc,
|
|
||||||
% Document root node: a string.
|
|
||||||
{yamerl_str, yamerl_node_str, "tag:yaml.org,2002:str",
|
|
||||||
[{line, 1}, {column, 1}], % Node location in the original string.
|
|
||||||
"Hello!" % String value.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
].
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Parse an invalid document
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:string(<<"'Oh-oh...">>). % Unfinished single-quoted scalar.
|
|
||||||
```
|
|
||||||
|
|
||||||
Throws an exception:
|
|
||||||
```erlang
|
|
||||||
{yamerl_exception,
|
|
||||||
% List of warnings and errors; here, one fatal error.
|
|
||||||
[
|
|
||||||
% Error #1.
|
|
||||||
{yamerl_parsing_error, error,
|
|
||||||
"Unexpected end-of-stream while parsing flow scalar", % Human-readable message.
|
|
||||||
1, 10, % Error location.
|
|
||||||
unexpected_eos,
|
|
||||||
{yamerl_scalar, 1, 1, {yamerl_tag, 1, 1, {non_specific, "!"}}, % Token being parsed.
|
|
||||||
flow, single_quoted,
|
|
||||||
"Oh-oh..."},
|
|
||||||
[]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}.
|
|
||||||
```
|
|
||||||
|
|
||||||
### Function: file(Filename)
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
|
|
||||||
Same as:
|
|
||||||
```erlang
|
|
||||||
yamerl_constr:file(Filename, []).
|
|
||||||
```
|
|
||||||
|
|
||||||
> See [`file/2`](#function-filefilename-options).
|
|
||||||
|
|
||||||
### Function: file(Filename, Options)
|
|
||||||
|
|
||||||
#### Arguments
|
|
||||||
|
|
||||||
* `Filename`: A string containing the filename to parse.
|
|
||||||
* `Options`: A proplist of options; see [`new/2`](#function-newsource-options).
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
|
|
||||||
Parse the file indicated by the given filename and return a list of constructed YAML documents.
|
|
||||||
|
|
||||||
The file is read by chunk of 4096 bytes (not configurable at this time).
|
|
||||||
|
|
||||||
Otherwise, the behavior is the same as [`string/2`](#function-stringstring-options).
|
|
||||||
|
|
||||||
> See [`string/2`](#function-stringstring-options) for return values, exceptions and examples.
|
|
@ -1,6 +0,0 @@
|
|||||||
# yamerl User Guide
|
|
||||||
|
|
||||||
## Recipes
|
|
||||||
|
|
||||||
* [Basic parsing](recipe-basic-parsing.md)
|
|
||||||
* [Error handling](recipe-error-handling.md)
|
|
@ -1,48 +0,0 @@
|
|||||||
# Recipe: Basic parsing
|
|
||||||
|
|
||||||
1. Start the yamerl application. This is a mandatory step.
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
application:start(yamerl).
|
|
||||||
```
|
|
||||||
|
|
||||||
2. You're now ready to parse a serialized document:
|
|
||||||
|
|
||||||
* To parse an in-memory string or binary:
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
Documents = yamerl_constr:string("Hello!").
|
|
||||||
% Documents is a list of constructed documents.
|
|
||||||
```
|
|
||||||
|
|
||||||
* To parse a file:
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
Documents = yamerl_constr:file("input.yaml").
|
|
||||||
% Documents is a list of constructed documents.
|
|
||||||
```
|
|
||||||
|
|
||||||
* To parse a stream:
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
% Create a new construction state. The only required argument is an
|
|
||||||
% arbitrary term describing the source of the data. Here, we use the
|
|
||||||
% same term structure as yamerl_constr:file/{1, 2}.
|
|
||||||
Constr_State = yamerl_constr:new({file, "<stdin>"}),
|
|
||||||
|
|
||||||
% Feed the parser with binary chunks. The developer is responsible for
|
|
||||||
% reading the chunk from the underlying source.
|
|
||||||
%
|
|
||||||
% The function returns an updated construction state, which replace the
|
|
||||||
% previous one.
|
|
||||||
%
|
|
||||||
% yamerl_constr:next_chunk/2 can be called as many times as possible.
|
|
||||||
{continue, Constr_State2} = yamerl_constr:next_chunk(Constr_State, Chunk),
|
|
||||||
|
|
||||||
% When the last chunk is reached, call yamerl_constr:last_chunk/2.
|
|
||||||
Documents = yamerl_constr:last_chunk(Constr_State2, Last_Chunk).
|
|
||||||
% Documents is a list of constructed documents.
|
|
||||||
```
|
|
||||||
|
|
||||||
> For further informations, see:
|
|
||||||
> * [yamerl\_constr module reference](../reference-manual/module-yamerl_constr.md);
|
|
@ -1,48 +0,0 @@
|
|||||||
# Recipe: Error handling
|
|
||||||
|
|
||||||
yamerl **throws an exception when an error occurs**.
|
|
||||||
|
|
||||||
1. Start the yamerl application. This is a mandatory step.
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
application:start(yamerl).
|
|
||||||
```
|
|
||||||
|
|
||||||
2. You're now ready to parse a serialized document:
|
|
||||||
|
|
||||||
* To parse an in-memory string or binary:
|
|
||||||
|
|
||||||
```erlang
|
|
||||||
-include_lib("yamerl/include/yamerl_errors.hrl").
|
|
||||||
|
|
||||||
% ...
|
|
||||||
|
|
||||||
try
|
|
||||||
Documents = yamerl_constr:string("Hello!"),
|
|
||||||
% Documents is a list of constructed documents.
|
|
||||||
Documents
|
|
||||||
catch
|
|
||||||
throw:#yamerl_exception{errors = Errors} ->
|
|
||||||
% Do something with the exception.
|
|
||||||
Errors
|
|
||||||
end.
|
|
||||||
```
|
|
||||||
|
|
||||||
As you can see, the `#yamerl_exception{}` record embeds all encountered errors:
|
|
||||||
```erlang
|
|
||||||
#yamerl_exception{
|
|
||||||
errors = [] % List of errors.
|
|
||||||
}.
|
|
||||||
```
|
|
||||||
|
|
||||||
Errors are records where the two first members are always:
|
|
||||||
|
|
||||||
1. `type`, either `error` or `warning`;
|
|
||||||
2. `text`, a human-readable error message.
|
|
||||||
|
|
||||||
Following members depend on the error record. Two records are currently defined:
|
|
||||||
* `#yamerl_invalid_option{}`;
|
|
||||||
* `#yamerl_parsing_error{}`.
|
|
||||||
|
|
||||||
> For further informations, see:
|
|
||||||
> * [yamerl\_constr module reference](../reference-manual/module-yamerl_constr.md);
|
|
237
doc/overview.edoc
Normal file
237
doc/overview.edoc
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
@author Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr>
|
||||||
|
@copyright
|
||||||
|
2012-2014 Yakaz,
|
||||||
|
2016 Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr>
|
||||||
|
|
||||||
|
@doc
|
||||||
|
|
||||||
|
== Introduction ==
|
||||||
|
|
||||||
|
YAML is a human-friendly data serialization format. The specification
|
||||||
|
for this language and many examples are available from the <a
|
||||||
|
href="http://www.yaml.org/">Official YAML web site</a>. You may also
|
||||||
|
want to check the <a href="http://en.wikipedia.org/wiki/YAML">YAML
|
||||||
|
Wikipedia article</a>.
|
||||||
|
|
||||||
|
<strong>`yamerl'</strong> is a pure <a
|
||||||
|
href="http://www.erlang.org/">Erlang application</a> which is able
|
||||||
|
to parse <a href="http://yaml.org/spec/1.1/">YAML 1.1</a> and <a
|
||||||
|
href="http://www.yaml.org/spec/1.2/spec.html">YAML 1.2</a> documents, as
|
||||||
|
well as <a href="http://json.org/">JSON</a> documents. It only depends
|
||||||
|
on standard Erlang/OTP applications; no external dependency is required.
|
||||||
|
It doesn't use native code either (neither port drivers nor NIFs). At
|
||||||
|
this time, it has no support to serialize a YAML document.
|
||||||
|
|
||||||
|
`yamerl' is distributed under the terms of the <strong>2-clause BSD
|
||||||
|
license</strong>; see `COPYING'.
|
||||||
|
|
||||||
|
== When to use yamerl or not ==
|
||||||
|
|
||||||
|
=== Advantages ===
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Pure Erlang implementation:
|
||||||
|
<ul>
|
||||||
|
<li>should scale more easily than a port-driver based implementation;</li>
|
||||||
|
<li>won't take the whole VM down in case of a crash.</li>
|
||||||
|
</ul></li>
|
||||||
|
<li>YAML 1.2 support, which is not widely supported in many other languages.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
=== Caveats ===
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Current implementation is slow, compared to yamler (NIF-based) or any JSON-only parsers.</li>
|
||||||
|
<li>Adding schemas is not easy.</li>
|
||||||
|
<li>No support for YAML serialization.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
== Features ==
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Supports <a href="http://www.yaml.org/spec/1.2/spec.html">YAML 1.2</a> parsing:
|
||||||
|
```
|
||||||
|
yamerl_constr:string("YAML snippet").
|
||||||
|
'''</li>
|
||||||
|
<li>Supports <a href="http://yaml.org/spec/1.1/">[YAML 1.1</a> parsing:
|
||||||
|
```
|
||||||
|
yamerl_constr:string("YAML snippet", [{schema, yaml11}]).
|
||||||
|
'''</li>
|
||||||
|
<li>Supports <a href="http://json.org/">JSON</a> parsing:
|
||||||
|
```
|
||||||
|
yamerl_constr:string(<<"JSON snippet">>, [{schema, json}]).
|
||||||
|
'''</li>
|
||||||
|
<li>Supports <strong>Erlang atom</strong> node type, either when tagged
|
||||||
|
as atom, or if autodetected in plain scalars, and, if asked, only if the
|
||||||
|
atom already exists:
|
||||||
|
```
|
||||||
|
% Enable support for Erlang atoms.
|
||||||
|
yamerl_app:set_param(node_mods, [yamerl_node_erlang_atom]),
|
||||||
|
yamerl_constr:string("!<tag:yamerl,2012:atom> atom").
|
||||||
|
|
||||||
|
% Autodetect Erlang atoms in plain scalars.
|
||||||
|
yamerl_app:set_param(node_mods, [yamerl_node_erlang_atom]),
|
||||||
|
yamerl_constr:string("atom", [{erlang_atom_autodetection, true}]).
|
||||||
|
|
||||||
|
% Atoms must already exist.
|
||||||
|
yamerl_app:set_param(node_mods, [yamerl_node_erlang_atom]),
|
||||||
|
yamerl_constr:string("atom", [
|
||||||
|
{erlang_atom_autodetection, true},
|
||||||
|
{erlang_atom_only_if_exist, true}
|
||||||
|
]).
|
||||||
|
'''</li>
|
||||||
|
<li>Supports <strong>Erlang fun()</strong> node type:
|
||||||
|
```
|
||||||
|
% Enable support for Erlang fun().
|
||||||
|
yamerl_app:set_param(node_mods, [yamerl_node_erlang_fun]),
|
||||||
|
[Plus_One_Fun] = yamerl_constr:string(<<"!<tag:yamerl,2012:fun> fun(X) -> X + 1 end.">>),
|
||||||
|
|
||||||
|
Plus_One_Fun(2). % Return 3.
|
||||||
|
'''</li>
|
||||||
|
<li>Provides a <strong>yamler compatibility layer</strong>:
|
||||||
|
```erlang
|
||||||
|
% Both calls return the same value.
|
||||||
|
yaml:load_file("input.yaml", [{schema, yaml_schema_failsafe}]),
|
||||||
|
yamerl_yamler_compat:load_file("input.yaml", [{schema, yaml_schema_failsafe}])
|
||||||
|
'''</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
== Prerequisites ==
|
||||||
|
|
||||||
|
Before using yamerl, the application must be started:
|
||||||
|
```
|
||||||
|
application:start(yamerl).
|
||||||
|
'''
|
||||||
|
|
||||||
|
This is required so that application environment variables are available.
|
||||||
|
|
||||||
|
Now, you can use the {@link yamerl_constr} module to parse and construct a
|
||||||
|
list of documents from:
|
||||||
|
<ul>
|
||||||
|
<li>an in-memory document (string or binary);</li>
|
||||||
|
<li>a regular file;</li>
|
||||||
|
<li>a stream.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
Because a YAML input stream may contain multiple documents, {@link
|
||||||
|
yamerl_constr} always returns a list of documents, even if the input
|
||||||
|
stream only contains one.
|
||||||
|
|
||||||
|
== Examples ==
|
||||||
|
|
||||||
|
=== Basic parsing ===
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>Start the yamerl application. This is a mandatory step.
|
||||||
|
```
|
||||||
|
application:start(yamerl).
|
||||||
|
'''</li>
|
||||||
|
<li>You're now ready to parse a serialized document:
|
||||||
|
<ul>
|
||||||
|
<li>To parse an in-memory string or binary:
|
||||||
|
```
|
||||||
|
Documents = yamerl_constr:string("Hello!").
|
||||||
|
% Documents is a list of constructed documents.
|
||||||
|
'''</li>
|
||||||
|
<li>To parse a file:
|
||||||
|
```
|
||||||
|
Documents = yamerl_constr:file("input.yaml").
|
||||||
|
% Documents is a list of constructed documents.
|
||||||
|
'''</li>
|
||||||
|
<li>To parse a stream:
|
||||||
|
```
|
||||||
|
% Create a new construction state. The only required argument is an
|
||||||
|
% arbitrary term describing the source of the data. Here, we use the
|
||||||
|
% same term structure as yamerl_constr:file/{1, 2}.
|
||||||
|
Constr_State = yamerl_constr:new({file, "<stdin>"}),
|
||||||
|
|
||||||
|
% Feed the parser with binary chunks. The developer is responsible for
|
||||||
|
% reading the chunk from the backing source.
|
||||||
|
%
|
||||||
|
% The function returns an updated construction state, which replaces the
|
||||||
|
% previous one.
|
||||||
|
%
|
||||||
|
% yamerl_constr:next_chunk/2 can be called as many times as necessary.
|
||||||
|
{continue, Constr_State2} = yamerl_constr:next_chunk(Constr_State, Chunk),
|
||||||
|
|
||||||
|
% When the last chunk is reached, call yamerl_constr:last_chunk/2.
|
||||||
|
Documents = yamerl_constr:last_chunk(Constr_State2, Last_Chunk).
|
||||||
|
% Documents is a list of constructed documents.
|
||||||
|
'''</li>
|
||||||
|
</ul></li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
See {@link yamerl_constr} for more informations.
|
||||||
|
|
||||||
|
=== Error handling ===
|
||||||
|
|
||||||
|
yamerl <strong>throws an exception when an error occurs</strong>.
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>Start the yamerl application. This is a mandatory step.
|
||||||
|
```
|
||||||
|
application:start(yamerl).
|
||||||
|
'''</li>
|
||||||
|
<li>You're now ready to parse a serialized document. To parse an
|
||||||
|
in-memory string or binary:
|
||||||
|
```
|
||||||
|
-include_lib("yamerl/include/yamerl_errors.hrl").
|
||||||
|
|
||||||
|
% ...
|
||||||
|
|
||||||
|
try
|
||||||
|
Documents = yamerl_constr:string("Hello!"),
|
||||||
|
% Documents is a list of constructed documents.
|
||||||
|
Documents
|
||||||
|
catch
|
||||||
|
throw:#yamerl_exception{errors = Errors} ->
|
||||||
|
% Do something with the exception.
|
||||||
|
Errors
|
||||||
|
end.
|
||||||
|
'''</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
As you can see, the `#yamerl_exception{}' record embeds all encountered
|
||||||
|
errors:
|
||||||
|
```
|
||||||
|
#yamerl_exception{
|
||||||
|
errors = [] % List of errors.
|
||||||
|
}.
|
||||||
|
'''
|
||||||
|
|
||||||
|
Errors are records where the two first members are always:
|
||||||
|
<ol>
|
||||||
|
<li>`type', either `error' or `warning';</li>
|
||||||
|
<li>`text', a human-readable error message.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
Following members depend on the error record. Two records are currently
|
||||||
|
defined:
|
||||||
|
<ul>
|
||||||
|
<li>`#yamerl_invalid_option{}';</li>
|
||||||
|
<li>`#yamerl_parsing_error{}'.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
See {@link yamerl_constr} for more informations.
|
||||||
|
|
||||||
|
== Alternatives to yamerl ==
|
||||||
|
|
||||||
|
=== YAML parsers ===
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://github.com/goertzenator/yamler">yamler</a>:
|
||||||
|
<ul>
|
||||||
|
<li>Based on libyaml, wrapped in a NIF</li>
|
||||||
|
<li>Supports YAML 1.1</li>
|
||||||
|
<li>Faster than yamerl</li>
|
||||||
|
<li>Supports Erlang atoms, however, single-quoted scalar are treated as
|
||||||
|
atom, which breaks the YAML specifications</li>
|
||||||
|
<li>Doesn't support Erlang fun()</li>
|
||||||
|
</ul></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
=== JSON parsers ===
|
||||||
|
|
||||||
|
There are too many to choose from now to list them here. Use your
|
||||||
|
preferred search engine :-)
|
@ -24,6 +24,13 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @author Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr>
|
||||||
|
%% @copyright
|
||||||
|
%% 2012-2014 Yakaz,
|
||||||
|
%% 2016 Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr>
|
||||||
|
%%
|
||||||
|
%% @doc Wrappers for common uses of {@link yamerl_constr}.
|
||||||
|
|
||||||
-module(yamerl).
|
-module(yamerl).
|
||||||
|
|
||||||
-include("yamerl_nodes.hrl").
|
-include("yamerl_nodes.hrl").
|
||||||
@ -44,6 +51,8 @@
|
|||||||
%% All those functions are only wrapper above yamerl_constr common
|
%% All those functions are only wrapper above yamerl_constr common
|
||||||
%% functions. The purpose is just to avoid some typing.
|
%% functions. The purpose is just to avoid some typing.
|
||||||
|
|
||||||
|
%% @equiv yamerl_constr:string(String)
|
||||||
|
|
||||||
-spec decode(String) ->
|
-spec decode(String) ->
|
||||||
Result | no_return() when
|
Result | no_return() when
|
||||||
String :: unicode_data(),
|
String :: unicode_data(),
|
||||||
@ -54,6 +63,8 @@
|
|||||||
decode(String) ->
|
decode(String) ->
|
||||||
yamerl_constr:string(String).
|
yamerl_constr:string(String).
|
||||||
|
|
||||||
|
%% @equiv yamerl_constr:string(String, Options)
|
||||||
|
|
||||||
-spec decode(String, Options) ->
|
-spec decode(String, Options) ->
|
||||||
Result | no_return() when
|
Result | no_return() when
|
||||||
String :: unicode_data(),
|
String :: unicode_data(),
|
||||||
@ -67,6 +78,8 @@ decode(String) ->
|
|||||||
decode(String, Options) ->
|
decode(String, Options) ->
|
||||||
yamerl_constr:string(String, Options).
|
yamerl_constr:string(String, Options).
|
||||||
|
|
||||||
|
%% @equiv yamerl_constr:file(Filename)
|
||||||
|
|
||||||
-spec decode_file(Filename) ->
|
-spec decode_file(Filename) ->
|
||||||
Result | no_return() when
|
Result | no_return() when
|
||||||
Filename :: string(),
|
Filename :: string(),
|
||||||
@ -77,6 +90,8 @@ decode(String, Options) ->
|
|||||||
decode_file(Filename) ->
|
decode_file(Filename) ->
|
||||||
yamerl_constr:file(Filename).
|
yamerl_constr:file(Filename).
|
||||||
|
|
||||||
|
%% @equiv yamerl_constr:file(Filename, Options)
|
||||||
|
|
||||||
-spec decode_file(Filename, Options) ->
|
-spec decode_file(Filename, Options) ->
|
||||||
Result | no_return() when
|
Result | no_return() when
|
||||||
Filename :: string(),
|
Filename :: string(),
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_app).
|
-module(yamerl_app).
|
||||||
|
|
||||||
-behaviour(application).
|
-behaviour(application).
|
||||||
|
@ -24,6 +24,64 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @author Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr>
|
||||||
|
%% @copyright
|
||||||
|
%% 2012-2014 Yakaz,
|
||||||
|
%% 2016 Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr>
|
||||||
|
%%
|
||||||
|
%% @doc {@module} implements a YAML constructor. It uses {@link
|
||||||
|
%% yamerl_parser} as the underlying parser. The parser emits YAML nodes
|
||||||
|
%% which are assembled as structured YAML documents by the constructor.
|
||||||
|
%%
|
||||||
|
%% It is able to construct YAML documents from in-memory strings (see
|
||||||
|
%% {@link string/1} and {@link string/2}), regular files (see {@link
|
||||||
|
%% file/1} and {@link file/2}) or streams (see {@link new/1}, {@link
|
||||||
|
%% new/2} and {@link next_chunk/3}).
|
||||||
|
%%
|
||||||
|
%% YAML documents can be constructed in simple or detailed modes. In
|
||||||
|
%% simple mode, they are made of simple builting Erlang types. In
|
||||||
|
%% detailed mode, they are made of records, holding more informations
|
||||||
|
%% about YAML nodes and their presentation.
|
||||||
|
%%
|
||||||
|
%% The `yamerl' application must be started to use the constructor.
|
||||||
|
%%
|
||||||
|
%% <strong>Example: parse a string in simple mode</strong>
|
||||||
|
%% ```
|
||||||
|
%% yamerl_constr:string("Hello!").
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% It returns:
|
||||||
|
%% ```
|
||||||
|
%% % List of documents; here, only one.
|
||||||
|
%% [
|
||||||
|
%% % Document root node: a string.
|
||||||
|
%% "Hello!"
|
||||||
|
%% ].
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% <strong>Example: parse a stream in detailed mode</strong>
|
||||||
|
%% ```
|
||||||
|
%% Stream_St1 = yamerl_constr:new({file, "<stdin>"}, [{detailed_constr, true}]),
|
||||||
|
%% {continue, Stream_St2} = yamerl_constr:next_chunk(Stream_St1, <<"He">>),
|
||||||
|
%% {continue, Stream_St3} = yamerl_constr:next_chunk(Stream_St2, <<"ll">>),
|
||||||
|
%% yamerl_constr:last_chunk(Stream_St3, <<"o!">>).
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% It returns:
|
||||||
|
%% ```
|
||||||
|
%% % List of documents; here, only one.
|
||||||
|
%% [
|
||||||
|
%% % Document #1.
|
||||||
|
%% {yamerl_doc,
|
||||||
|
%% % Document root node: a string.
|
||||||
|
%% {yamerl_str, yamerl_node_str, "tag:yaml.org,2002:str",
|
||||||
|
%% [{line, 1}, {column, 1}], % Node location in the original string.
|
||||||
|
%% "Hello!" % String value.
|
||||||
|
%% }
|
||||||
|
%% }
|
||||||
|
%% ].
|
||||||
|
%% '''
|
||||||
|
|
||||||
-module(yamerl_constr).
|
-module(yamerl_constr).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
@ -96,6 +154,8 @@
|
|||||||
%% Public API: chunked stream scanning.
|
%% Public API: chunked stream scanning.
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% @equiv new(Source, [])
|
||||||
|
|
||||||
-spec new(Source) ->
|
-spec new(Source) ->
|
||||||
Constr | no_return() when
|
Constr | no_return() when
|
||||||
Source :: term(),
|
Source :: term(),
|
||||||
@ -104,29 +164,141 @@
|
|||||||
new(Source) ->
|
new(Source) ->
|
||||||
new(Source, []).
|
new(Source, []).
|
||||||
|
|
||||||
|
%% @doc Creates and returns a new YAML construction state.
|
||||||
|
%%
|
||||||
|
%% When you want to parse a stream (as opposed to in-memory strings or
|
||||||
|
%% regular files), this is the first function you call before feeding
|
||||||
|
%% the constructor with stream "chunks".
|
||||||
|
%%
|
||||||
|
%% `Source' can be any term describing the stream. {@link string/1} and
|
||||||
|
%% {@link string/2} sets it to the atom `string'. {@link file/1} and
|
||||||
|
%% {@link file/2} sets it to `{file, Filename}'. The constructor doesn't
|
||||||
|
%% use that value.
|
||||||
|
%%
|
||||||
|
%% `Options' is a list of options for the parser and the constructor.
|
||||||
|
%% Valid options are:
|
||||||
|
%%
|
||||||
|
%% <dl>
|
||||||
|
%% <dt>`{detailed_constr, boolean()}'</dt>
|
||||||
|
%% <dd>Flag to enable/disable the detailed construction mode. In simple
|
||||||
|
%% construction mode, YAML nodes are returned as Erlang integers,
|
||||||
|
%% strings, lists, proplists, etc. In other words, only simple builtin
|
||||||
|
%% types. In detailed construction mode, YAML nodes are returned using
|
||||||
|
%% records. Those records gives additional informations such as the YAML
|
||||||
|
%% node type, the location in the stream (line and column number) and so
|
||||||
|
%% on.</dd>
|
||||||
|
%% <dd>Default: `false'</dd>
|
||||||
|
%% <dt>`{schema, failsafe | json | core | yaml11}'</dt>
|
||||||
|
%% <dd>Name of the official schema to use.</dd>
|
||||||
|
%% <dd>Default: `core'.</dd>
|
||||||
|
%% <dt>`{node_mods, Mods_List}'</dt>
|
||||||
|
%% <dd>List of Erlang modules to extend support node types.</dd>
|
||||||
|
%% <dd>Default: `[]'.</dd>
|
||||||
|
%% </dl>
|
||||||
|
%%
|
||||||
|
%% The returned state is opaque value. You then pass it to {@link
|
||||||
|
%% next_chunk/2}, {@link next_chunk/3} and {@link last_chunk/2}.
|
||||||
|
%%
|
||||||
|
%% If an option is invalid, an exception is thrown.
|
||||||
|
%%
|
||||||
|
%% <strong>Example: parse a valid stream</strong>
|
||||||
|
%% ```
|
||||||
|
%% Stream_St1 = yamerl_constr:new({file, "<stdin>"}),
|
||||||
|
%% {continue, Stream_St2} = yamerl_constr:next_chunk(Stream_St1, <<"He">>),
|
||||||
|
%% {continue, Stream_St3} = yamerl_constr:next_chunk(Stream_St2, <<"ll">>),
|
||||||
|
%% yamerl_constr:last_chunk(Stream_St3, <<"o!">>).
|
||||||
|
%% '''
|
||||||
|
%% It returns:
|
||||||
|
%%
|
||||||
|
%% ```
|
||||||
|
%% % List of documents; here, only one.
|
||||||
|
%% [
|
||||||
|
%% % Document root node: a string.
|
||||||
|
%% "Hello!"
|
||||||
|
%% ].
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% <strong>Example: parse an invalid stream</strong>
|
||||||
|
%% ```
|
||||||
|
%% Stream_St1 = yamerl_constr:new({file, "<stdin>"}),
|
||||||
|
%% {continue, Stream_St2} = yamerl_constr:next_chunk(Stream_St1, <<"'He">>),
|
||||||
|
%% {continue, Stream_St3} = yamerl_constr:next_chunk(Stream_St2, <<"ll">>),
|
||||||
|
%% yamerl_constr:last_chunk(Stream_St3, <<"o!">>) % Unfinished single-quoted scalar.
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% It throws:
|
||||||
|
%% ```
|
||||||
|
%% {yamerl_exception,
|
||||||
|
%% % List of warnings and errors; here, one fatal error.
|
||||||
|
%% [
|
||||||
|
%% % Error #1.
|
||||||
|
%% {yamerl_parsing_error, error,
|
||||||
|
%% "Unexpected end-of-stream while parsing flow scalar", % Human-readable message.
|
||||||
|
%% 1, 8, % Error location.
|
||||||
|
%% unexpected_eos,
|
||||||
|
%% {yamerl_scalar, 1, 1, {yamerl_tag, 1, 1, {non_specific, "!"}}, % Token being parsed.
|
||||||
|
%% flow, single_quoted,
|
||||||
|
%% "Hello!"},
|
||||||
|
%% []
|
||||||
|
%% }
|
||||||
|
%% ]
|
||||||
|
%% }
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% @see new/1.
|
||||||
|
|
||||||
-spec new(Source, Options) ->
|
-spec new(Source, Options) ->
|
||||||
Constr | no_return() when
|
Constr | no_return() when
|
||||||
Source :: term(),
|
Source :: term(),
|
||||||
Options :: [
|
Options :: [
|
||||||
yamerl_constr_option() |
|
yamerl_constr_option() |
|
||||||
yamerl_parser:yamerl_parser_option() |
|
yamerl_parser:yamerl_parser_option() |
|
||||||
proplists:property()
|
proplists:property()
|
||||||
],
|
],
|
||||||
Constr :: yamerl_parser:yamerl_parser().
|
Constr :: yamerl_parser:yamerl_parser().
|
||||||
|
|
||||||
new(Source, Options) ->
|
new(Source, Options) ->
|
||||||
Parser_Options = initialize(Options),
|
Parser_Options = initialize(Options),
|
||||||
yamerl_parser:new(Source, Parser_Options).
|
yamerl_parser:new(Source, Parser_Options).
|
||||||
|
|
||||||
|
%% @equiv next_chunk(Constr, Chunk, false)
|
||||||
|
|
||||||
-spec next_chunk(Constr, Chunk) ->
|
-spec next_chunk(Constr, Chunk) ->
|
||||||
Ret | no_return() when
|
Ret | no_return() when
|
||||||
Constr :: yamerl_parser:yamerl_parser(),
|
Constr :: yamerl_parser:yamerl_parser(),
|
||||||
Chunk :: unicode_binary(),
|
Chunk :: unicode_binary(),
|
||||||
Ret :: {continue, New_Constr},
|
Ret :: {continue, New_Constr},
|
||||||
New_Constr :: yamerl_parser:yamerl_parser().
|
New_Constr :: yamerl_parser:yamerl_parser().
|
||||||
|
|
||||||
next_chunk(Constr, Chunk) ->
|
next_chunk(Constr, Chunk) ->
|
||||||
next_chunk(Constr, Chunk, false).
|
next_chunk(Constr, Chunk, false).
|
||||||
|
|
||||||
|
%% @doc Feeds the constructor with the next chunk from the YAML stream.
|
||||||
|
%%
|
||||||
|
%% `Constr' is the constructor state returned by a previous call
|
||||||
|
%% to {@link new/1}, {@link new/2}, {@link next_chunk/2} or {@link
|
||||||
|
%% next_chunk/3}.
|
||||||
|
%%
|
||||||
|
%% `Chunk' must be an Erlang binary using the UTF-8, UTF-16 or UTF-32
|
||||||
|
%% Unicode encoding. A leading BOM character in the first chunk is used
|
||||||
|
%% to determine the encoding and endianness. If no BOM is present, UTF-8
|
||||||
|
%% is assumed.
|
||||||
|
%%
|
||||||
|
%% `EOS' indicates the constructor if this is the last chunk from the
|
||||||
|
%% stream.
|
||||||
|
%%
|
||||||
|
%% If this is not the last chunk (`EOS = false'), it returns `{continue,
|
||||||
|
%% New_Constr}' where `New_Constr' is an updated state which replaces
|
||||||
|
%% `Constr'. The new state is to be passed to future calls to {@link
|
||||||
|
%% next_chunk/2}, {@link next_chunk/3} or {@link last_chunk/2}.
|
||||||
|
%%
|
||||||
|
%% If this is the last chunk (`EOS = true'), it returns a list of YAML
|
||||||
|
%% documents. Documents are made of simple builtin Erlang types if the
|
||||||
|
%% detailed construction mode is disabled, or records if the detailed
|
||||||
|
%% construction mode is enabled (`{detailed_constr, boolean()}' passed
|
||||||
|
%% as an option; default is `false').
|
||||||
|
%%
|
||||||
|
%% It throws an exception if there is a parsing or construction error.
|
||||||
|
|
||||||
-spec next_chunk(Constr, Chunk, false) ->
|
-spec next_chunk(Constr, Chunk, false) ->
|
||||||
Ret | no_return() when
|
Ret | no_return() when
|
||||||
@ -148,6 +320,8 @@ next_chunk(Constr, Chunk, EOS) ->
|
|||||||
true -> Ret
|
true -> Ret
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% @equiv next_chunk(Constr, Chunk, true)
|
||||||
|
|
||||||
-spec last_chunk(Constr, Chunk) ->
|
-spec last_chunk(Constr, Chunk) ->
|
||||||
Result | no_return() when
|
Result | no_return() when
|
||||||
Constr :: yamerl_parser:yamerl_parser(),
|
Constr :: yamerl_parser:yamerl_parser(),
|
||||||
@ -179,6 +353,8 @@ get_docs(Constr) ->
|
|||||||
%% Public API: common stream sources.
|
%% Public API: common stream sources.
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% @equiv string(String, [])
|
||||||
|
|
||||||
-spec string(String) ->
|
-spec string(String) ->
|
||||||
Result | no_return() when
|
Result | no_return() when
|
||||||
String :: unicode_data(),
|
String :: unicode_data(),
|
||||||
@ -189,6 +365,89 @@ get_docs(Constr) ->
|
|||||||
string(String) ->
|
string(String) ->
|
||||||
string(String, []).
|
string(String, []).
|
||||||
|
|
||||||
|
%% @doc Constructs a YAML document from an in-memory YAML string.
|
||||||
|
%%
|
||||||
|
%% `String' must be an Erlang list or binary containing one or more YAML
|
||||||
|
%% documents. If it is a binary, it must be encoded using UTF-8, UTF-16
|
||||||
|
%% or UTF-32. A leading BOM character is used to determine the encoding
|
||||||
|
%% and endianness. If no BOM is present, UTF-8 is assumed.
|
||||||
|
%%
|
||||||
|
%% `Options' is a list of options for the parser and the constructor.
|
||||||
|
%% See {@link new/2} for valid options.
|
||||||
|
%%
|
||||||
|
%% It returns a list of YAML documents. See {@link next_chunk/3} for
|
||||||
|
%% more details about the returned documents.
|
||||||
|
%%
|
||||||
|
%% It throws an exception if there is a parsing or construction error.
|
||||||
|
%%
|
||||||
|
%% <strong>Example: parse an Erlang list</strong>
|
||||||
|
%% ```
|
||||||
|
%% yamerl_constr:string("This is a string").
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% <strong>Example: parse an UTF-8-encoded Erlang binary</strong>
|
||||||
|
%% ```
|
||||||
|
%% yamerl_constr:string(<<50,32,226,130,172>>). % The string "2 €" encoded in UTF-8.
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% <strong>Example: parse a string in simple mode</strong>
|
||||||
|
%% ```
|
||||||
|
%% yamerl_constr:string("Hello!").
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% It returns:
|
||||||
|
%% ```
|
||||||
|
%% % List of documents; here, only one.
|
||||||
|
%% [
|
||||||
|
%% % Document root node: a string.
|
||||||
|
%% "Hello!"
|
||||||
|
%% ].
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% <strong>Example: parse a string in detailed mode</strong>
|
||||||
|
%% ```
|
||||||
|
%% yamerl_constr:string("Hello!", [{detailed_constr, true}]).
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% It returns:
|
||||||
|
%% ```
|
||||||
|
%% % List of documents; here, only one.
|
||||||
|
%% [
|
||||||
|
%% % Document #1.
|
||||||
|
%% {yamerl_doc,
|
||||||
|
%% % Document root node: a string.
|
||||||
|
%% {yamerl_str, yamerl_node_str, "tag:yaml.org,2002:str",
|
||||||
|
%% [{line, 1}, {column, 1}], % Node location in the original string.
|
||||||
|
%% "Hello!" % String value.
|
||||||
|
%% }
|
||||||
|
%% }
|
||||||
|
%% ].
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% <strong>Example: parse an invalid document</strong>
|
||||||
|
%% ```
|
||||||
|
%% yamerl_constr:string(<<"'Oh-oh...">>). % Unfinished single-quoted scalar.
|
||||||
|
%% '''
|
||||||
|
%%
|
||||||
|
%% It throws:
|
||||||
|
%% ```
|
||||||
|
%% {yamerl_exception,
|
||||||
|
%% % List of warnings and errors; here, one fatal error.
|
||||||
|
%% [
|
||||||
|
%% % Error #1.
|
||||||
|
%% {yamerl_parsing_error, error,
|
||||||
|
%% "Unexpected end-of-stream while parsing flow scalar", % Human-readable message.
|
||||||
|
%% 1, 10, % Error location.
|
||||||
|
%% unexpected_eos,
|
||||||
|
%% {yamerl_scalar, 1, 1, {yamerl_tag, 1, 1, {non_specific, "!"}}, % Token being parsed.
|
||||||
|
%% flow, single_quoted,
|
||||||
|
%% "Oh-oh..."},
|
||||||
|
%% []
|
||||||
|
%% }
|
||||||
|
%% ]
|
||||||
|
%% }.
|
||||||
|
%% '''
|
||||||
|
|
||||||
-spec string(String, Options) ->
|
-spec string(String, Options) ->
|
||||||
Result | no_return() when
|
Result | no_return() when
|
||||||
String :: unicode_data(),
|
String :: unicode_data(),
|
||||||
@ -211,9 +470,28 @@ string(String, Options) ->
|
|||||||
| [yamerl_simple_doc()]
|
| [yamerl_simple_doc()]
|
||||||
| term().
|
| term().
|
||||||
|
|
||||||
|
%% @equiv file(Filename, [])
|
||||||
|
|
||||||
file(Filename) ->
|
file(Filename) ->
|
||||||
file(Filename, []).
|
file(Filename, []).
|
||||||
|
|
||||||
|
%% @doc Constructs a YAML document from a regular file.
|
||||||
|
%%
|
||||||
|
%% `Filename' must be a string indicating the filename. The file must
|
||||||
|
%% contain one or more YAML documents. The file must be encoded using
|
||||||
|
%% UTF-8, UTF-16 or UTF-32. A leading BOM character is used to determine
|
||||||
|
%% the encoding and endianness. If no BOM is present, UTF-8 is assumed.
|
||||||
|
%%
|
||||||
|
%% `Options' is a list of options for the parser and the constructor.
|
||||||
|
%% See {@link new/2} for valid options.
|
||||||
|
%%
|
||||||
|
%% It returns a list of YAML documents. See {@link next_chunk/3} for
|
||||||
|
%% more details about the returned documents.
|
||||||
|
%%
|
||||||
|
%% It throws an exception if there is a parsing or construction error.
|
||||||
|
%%
|
||||||
|
%% See {@link string/2} for some examples.
|
||||||
|
|
||||||
-spec file(Filename, Options) ->
|
-spec file(Filename, Options) ->
|
||||||
Result | no_return() when
|
Result | no_return() when
|
||||||
Filename :: string(),
|
Filename :: string(),
|
||||||
@ -233,6 +511,13 @@ file(Filename, Options) ->
|
|||||||
%% Presentation details.
|
%% Presentation details.
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% @doc Returns presentation informations in the stream for the given
|
||||||
|
%% node.
|
||||||
|
%%
|
||||||
|
%% This only makes sense when the detailed construction mode is enabled
|
||||||
|
%% (ie. `{detailed_constr, true}' was passed as an option to {@link
|
||||||
|
%% new/2}, {@link file/2} or {@link string/2}).
|
||||||
|
|
||||||
get_pres_details(Token) ->
|
get_pres_details(Token) ->
|
||||||
Line = ?TOKEN_LINE(Token),
|
Line = ?TOKEN_LINE(Token),
|
||||||
Column = ?TOKEN_COLUMN(Token),
|
Column = ?TOKEN_COLUMN(Token),
|
||||||
@ -242,12 +527,24 @@ get_pres_details(Token) ->
|
|||||||
%% Node informations.
|
%% Node informations.
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% @doc Returns the line number in the stream for the given node.
|
||||||
|
%%
|
||||||
|
%% This only makes sense when the detailed construction mode is enabled
|
||||||
|
%% (ie. `{detailed_constr, true}' was passed as an option to {@link
|
||||||
|
%% new/2}, {@link file/2} or {@link string/2}).
|
||||||
|
|
||||||
node_line(Node) ->
|
node_line(Node) ->
|
||||||
case node_pres(Node) of
|
case node_pres(Node) of
|
||||||
undefined -> undefined;
|
undefined -> undefined;
|
||||||
Pres -> proplists:get_value(line, Pres)
|
Pres -> proplists:get_value(line, Pres)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% @doc Returns the column number in the stream for the given node.
|
||||||
|
%%
|
||||||
|
%% This only makes sense when the detailed construction mode is enabled
|
||||||
|
%% (ie. `{detailed_constr, true}' was passed as an option to {@link
|
||||||
|
%% new/2}, {@link file/2} or {@link string/2}).
|
||||||
|
|
||||||
node_column(Node) ->
|
node_column(Node) ->
|
||||||
case node_pres(Node) of
|
case node_pres(Node) of
|
||||||
undefined -> undefined;
|
undefined -> undefined;
|
||||||
@ -553,6 +850,8 @@ filter_options2([], _, _, Constr_Options, Parser_Options, Ext_Options) ->
|
|||||||
lists:reverse(Ext_Options)
|
lists:reverse(Ext_Options)
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
option_names() ->
|
option_names() ->
|
||||||
[
|
[
|
||||||
node_mods,
|
node_mods,
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_errors).
|
-module(yamerl_errors).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_bool).
|
-module(yamerl_node_bool).
|
||||||
|
|
||||||
-include("yamerl_tokens.hrl").
|
-include("yamerl_tokens.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_bool_ext).
|
-module(yamerl_node_bool_ext).
|
||||||
|
|
||||||
-include("yamerl_tokens.hrl").
|
-include("yamerl_tokens.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_bool_json).
|
-module(yamerl_node_bool_json).
|
||||||
|
|
||||||
-include("yamerl_tokens.hrl").
|
-include("yamerl_tokens.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_erlang_atom).
|
-module(yamerl_node_erlang_atom).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_erlang_fun).
|
-module(yamerl_node_erlang_fun).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_float).
|
-module(yamerl_node_float).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_float_ext).
|
-module(yamerl_node_float_ext).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_float_json).
|
-module(yamerl_node_float_json).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_int).
|
-module(yamerl_node_int).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_int_ext).
|
-module(yamerl_node_int_ext).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_int_json).
|
-module(yamerl_node_int_json).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_ipaddr).
|
-module(yamerl_node_ipaddr).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_map).
|
-module(yamerl_node_map).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_null).
|
-module(yamerl_node_null).
|
||||||
|
|
||||||
-include("yamerl_tokens.hrl").
|
-include("yamerl_tokens.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_null_json).
|
-module(yamerl_node_null_json).
|
||||||
|
|
||||||
-include("yamerl_tokens.hrl").
|
-include("yamerl_tokens.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_seq).
|
-module(yamerl_node_seq).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_size).
|
-module(yamerl_node_size).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_str).
|
-module(yamerl_node_str).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_str_json).
|
-module(yamerl_node_str_json).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_node_timestamp).
|
-module(yamerl_node_timestamp).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
|
@ -24,6 +24,16 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @author Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr>
|
||||||
|
%% @copyright
|
||||||
|
%% 2012-2014 Yakaz,
|
||||||
|
%% 2016 Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr>
|
||||||
|
%%
|
||||||
|
%% @doc {@module} implements a YAML parser. It is not meant to be used
|
||||||
|
%% directly. Instead, you should use {@link yamerl_constr}.
|
||||||
|
%%
|
||||||
|
%% The `yamerl' application must be started to use the parser.
|
||||||
|
|
||||||
-module(yamerl_parser).
|
-module(yamerl_parser).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
@ -276,6 +286,8 @@
|
|||||||
%% Public API: chunked stream scanning.
|
%% Public API: chunked stream scanning.
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% @equiv new(Source, [])
|
||||||
|
|
||||||
-spec new(Source) ->
|
-spec new(Source) ->
|
||||||
Parser | no_return() when
|
Parser | no_return() when
|
||||||
Source :: term(),
|
Source :: term(),
|
||||||
@ -284,6 +296,8 @@
|
|||||||
new(Source) ->
|
new(Source) ->
|
||||||
new(Source, []).
|
new(Source, []).
|
||||||
|
|
||||||
|
%% @doc Creates and returns a new YAML parser state.
|
||||||
|
|
||||||
-spec new(Source, Options) ->
|
-spec new(Source, Options) ->
|
||||||
Parser | no_return() when
|
Parser | no_return() when
|
||||||
Source :: term(),
|
Source :: term(),
|
||||||
@ -300,6 +314,8 @@ new(Source, Options) ->
|
|||||||
token_fun = proplists:get_value(token_fun, Options0, acc)
|
token_fun = proplists:get_value(token_fun, Options0, acc)
|
||||||
}.
|
}.
|
||||||
|
|
||||||
|
%% @equiv next_chunk(Parser, Chunk, false)
|
||||||
|
|
||||||
-spec next_chunk(Parser, Chunk) ->
|
-spec next_chunk(Parser, Chunk) ->
|
||||||
Ret | no_return() when
|
Ret | no_return() when
|
||||||
Parser :: yamerl_parser(),
|
Parser :: yamerl_parser(),
|
||||||
@ -310,6 +326,8 @@ new(Source, Options) ->
|
|||||||
next_chunk(Parser, Chunk) ->
|
next_chunk(Parser, Chunk) ->
|
||||||
next_chunk(Parser, Chunk, false).
|
next_chunk(Parser, Chunk, false).
|
||||||
|
|
||||||
|
%% @doc Feeds the parser with the next chunk from the YAML stream.
|
||||||
|
|
||||||
-spec next_chunk(Parser, Chunk, Last_Chunk) ->
|
-spec next_chunk(Parser, Chunk, Last_Chunk) ->
|
||||||
Ret | no_return() when
|
Ret | no_return() when
|
||||||
Parser :: yamerl_parser(),
|
Parser :: yamerl_parser(),
|
||||||
@ -331,6 +349,8 @@ next_chunk(#yamerl_parser{raw_data = Data} = Parser, Chunk, EOS) ->
|
|||||||
},
|
},
|
||||||
decode_unicode(Parser1).
|
decode_unicode(Parser1).
|
||||||
|
|
||||||
|
%% @equiv next_chunk(Parser, Chunk, true)
|
||||||
|
|
||||||
-spec last_chunk(Parser, Chunk) ->
|
-spec last_chunk(Parser, Chunk) ->
|
||||||
Ret | no_return() when
|
Ret | no_return() when
|
||||||
Parser :: yamerl_parser(),
|
Parser :: yamerl_parser(),
|
||||||
@ -345,6 +365,8 @@ last_chunk(Parser, Chunk) ->
|
|||||||
%% Public API: common stream sources.
|
%% Public API: common stream sources.
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% @equiv string(String, [])
|
||||||
|
|
||||||
-spec string(String) ->
|
-spec string(String) ->
|
||||||
Parser | no_return() when
|
Parser | no_return() when
|
||||||
String :: unicode_data(),
|
String :: unicode_data(),
|
||||||
@ -353,6 +375,8 @@ last_chunk(Parser, Chunk) ->
|
|||||||
string(String) ->
|
string(String) ->
|
||||||
string(String, []).
|
string(String, []).
|
||||||
|
|
||||||
|
%% @doc Parses a YAML document from an in-memory YAML string.
|
||||||
|
|
||||||
-spec string(String, Options) ->
|
-spec string(String, Options) ->
|
||||||
Parser | no_return() when
|
Parser | no_return() when
|
||||||
String :: unicode_data(),
|
String :: unicode_data(),
|
||||||
@ -365,6 +389,8 @@ string(String, Options) when is_binary(String) ->
|
|||||||
string(String, Options) when is_list(String) ->
|
string(String, Options) when is_list(String) ->
|
||||||
string(unicode:characters_to_binary(String), Options).
|
string(unicode:characters_to_binary(String), Options).
|
||||||
|
|
||||||
|
%% @equiv file(Filename, [])
|
||||||
|
|
||||||
-spec file(Filename) ->
|
-spec file(Filename) ->
|
||||||
Parser | no_return() when
|
Parser | no_return() when
|
||||||
Filename :: string(),
|
Filename :: string(),
|
||||||
@ -373,6 +399,8 @@ string(String, Options) when is_list(String) ->
|
|||||||
file(Filename) ->
|
file(Filename) ->
|
||||||
file(Filename, []).
|
file(Filename, []).
|
||||||
|
|
||||||
|
%% @doc Parses a YAML document from a regular file.
|
||||||
|
|
||||||
-spec file(Filename, Options) ->
|
-spec file(Filename, Options) ->
|
||||||
Parser | no_return() when
|
Parser | no_return() when
|
||||||
Filename :: string(),
|
Filename :: string(),
|
||||||
@ -440,9 +468,13 @@ file2(#yamerl_parser{source = {file, Filename}} = Parser, FD, Blocksize) ->
|
|||||||
%% Public API: get/set the token function.
|
%% Public API: get/set the token function.
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% @doc Returns the constructor callback function
|
||||||
|
|
||||||
get_token_fun(#yamerl_parser{token_fun = Fun}) ->
|
get_token_fun(#yamerl_parser{token_fun = Fun}) ->
|
||||||
Fun.
|
Fun.
|
||||||
|
|
||||||
|
%% @doc Sets the constructor callback function
|
||||||
|
|
||||||
set_token_fun(Parser, Fun) when is_function(Fun, 1) ->
|
set_token_fun(Parser, Fun) when is_function(Fun, 1) ->
|
||||||
Parser#yamerl_parser{token_fun = Fun}.
|
Parser#yamerl_parser{token_fun = Fun}.
|
||||||
|
|
||||||
@ -4203,6 +4235,8 @@ setup_default_tags(#yamerl_parser{options = Options} = Parser) ->
|
|||||||
%% Internal functions.
|
%% Internal functions.
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
option_names() ->
|
option_names() ->
|
||||||
[
|
[
|
||||||
default_tags,
|
default_tags,
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-module(yamerl_sup).
|
-module(yamerl_sup).
|
||||||
|
|
||||||
-behaviour(supervisor).
|
-behaviour(supervisor).
|
||||||
|
@ -24,6 +24,16 @@
|
|||||||
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
% SUCH DAMAGE.
|
% SUCH DAMAGE.
|
||||||
|
|
||||||
|
%% @author Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr>
|
||||||
|
%% @copyright
|
||||||
|
%% 2012-2014 Yakaz,
|
||||||
|
%% 2016 Jean-Sébastien Pédron <jean-sebastien.pedron@dumbbell.fr>
|
||||||
|
%%
|
||||||
|
%% @doc {@module} implements the <em>yamerl</em> API above {@link
|
||||||
|
%% yamerl_constr}.
|
||||||
|
%%
|
||||||
|
%% See <em>yamler</em> documentation: [https://github.com/goertzenator/yamler].
|
||||||
|
|
||||||
-module(yamerl_yamler_compat).
|
-module(yamerl_yamler_compat).
|
||||||
|
|
||||||
-include("yamerl_errors.hrl").
|
-include("yamerl_errors.hrl").
|
||||||
@ -50,6 +60,8 @@
|
|||||||
%% Public API.
|
%% Public API.
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% @equiv load(String, [])
|
||||||
|
|
||||||
-spec load(String) ->
|
-spec load(String) ->
|
||||||
Result | Error when
|
Result | Error when
|
||||||
String :: binary(),
|
String :: binary(),
|
||||||
@ -60,6 +72,10 @@
|
|||||||
load(String) ->
|
load(String) ->
|
||||||
load(String, []).
|
load(String, []).
|
||||||
|
|
||||||
|
%% @doc Constructs a YAML document from an in-memory string.
|
||||||
|
%%
|
||||||
|
%% The `yamerl' application must be started to use this wrapper.
|
||||||
|
|
||||||
-spec load(String, Options) ->
|
-spec load(String, Options) ->
|
||||||
Result | Error when
|
Result | Error when
|
||||||
String :: binary(),
|
String :: binary(),
|
||||||
@ -78,6 +94,8 @@ load(String, Options) ->
|
|||||||
format_error(Error)
|
format_error(Error)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% @equiv load_file(Filename, [])
|
||||||
|
|
||||||
-spec load_file(Filename) ->
|
-spec load_file(Filename) ->
|
||||||
Result | Error when
|
Result | Error when
|
||||||
Filename :: string(),
|
Filename :: string(),
|
||||||
@ -88,6 +106,8 @@ load(String, Options) ->
|
|||||||
load_file(Filename) ->
|
load_file(Filename) ->
|
||||||
load_file(Filename, []).
|
load_file(Filename, []).
|
||||||
|
|
||||||
|
%% @doc Constructs a YAML document from a regular file.
|
||||||
|
|
||||||
-spec load_file(Filename, Options) ->
|
-spec load_file(Filename, Options) ->
|
||||||
Result | Error when
|
Result | Error when
|
||||||
Filename :: string(),
|
Filename :: string(),
|
||||||
@ -106,6 +126,8 @@ load_file(Filename, Options) ->
|
|||||||
format_error(Error)
|
format_error(Error)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
-spec convert_options(Options) ->
|
-spec convert_options(Options) ->
|
||||||
Converted when
|
Converted when
|
||||||
Options :: [yamler_option()],
|
Options :: [yamler_option()],
|
||||||
@ -118,6 +140,8 @@ load_file(Filename, Options) ->
|
|||||||
convert_options(Options) ->
|
convert_options(Options) ->
|
||||||
convert_options(Options, []).
|
convert_options(Options, []).
|
||||||
|
|
||||||
|
%% @private
|
||||||
|
|
||||||
convert_options([{schema, yaml_schema_failsafe} | Rest], Converted) ->
|
convert_options([{schema, yaml_schema_failsafe} | Rest], Converted) ->
|
||||||
Converted1 = [
|
Converted1 = [
|
||||||
{schema, failsafe}
|
{schema, failsafe}
|
||||||
|
Loading…
Reference in New Issue
Block a user