on master help sign in
.github/workflows/tests.ymlnew file+44
since splitsnapshots
unifiedsplit
@@ -0,0 +1,44 @@
1+name: Tests
2+
3+on:
4+ pull_request:
5+ push:
6+ branches:
7+ - master
8+
9+jobs:
10+ build:
11+ name: CI
12+ runs-on: ${{ matrix.os }}
13+ strategy:
14+ fail-fast: false
15+ matrix:
16+ os: [ubuntu-latest, macos-latest, windows-latest]
17+ resolver: [nightly, lts-22, lts-20, lts-17]
18+ exclude:
19+ - os: windows-latest
20+ resolver: lts-15
21+ - os: windows-latest
22+ resolver: nightly
23+
24+ steps:
25+ - name: Clone project
26+ uses: actions/checkout@v3
27+
28+ - name: Cache dependencies
29+ if: ${{ runner.os != 'Windows' }}
30+ # Andreas Abel, 2023-06-10, switching off caching on Windows since ~/.stack is not the correct path here.
31+ uses: actions/cache@v3
32+ with:
33+ path: ~/.stack
34+ #NB: This path is not valid on Windows
35+ key: ${{ runner.os }}-${{ matrix.resolver }}-${{ hashFiles('stack.yaml') }}
36+ restore-keys: |
37+ ${{ runner.os }}-${{ matrix.resolver }}-
38+
39+ - name: Build and run tests
40+ shell: bash
41+ run: |
42+ set -ex
43+ stack upgrade || curl -sSL https://get.haskellstack.org/ | sh -s - -f
44+ stack test --bench --no-run-benchmarks --haddock --no-haddock-deps --no-terminal --resolver=${{ matrix.resolver }}
.gitignore+2−2
@@ -5,7 +5,7 @@ cabal-dev/
5cabal.sandbox.config
5cabal.sandbox.config
6.stack-work/
6.stack-work/
7*~
7*~
8−yaml.cabal
9−/tarballs/
8+tarballs/
10.dir-locals.el
9.dir-locals.el
11*#
10*#
11+stack.yaml.lock
.gitmodules+1−1
@@ -1,3 +1,3 @@
1[submodule "vendor/libyaml"]
1[submodule "vendor/libyaml"]
2− path = vendor/libyaml
2+ path = libyaml/vendor/libyaml
3 url = https://github.com/snoyberg/libyaml
3 url = https://github.com/snoyberg/libyaml
.travis.ymldeleted−232
@@ -1,232 +0,0 @@
1−# This is the complex Travis configuration, which is intended for use
2−# on open source libraries which need compatibility across multiple GHC
3−# versions, must work with cabal-install, and should be
4−# cross-platform. For more information and other options, see:
5−#
6−# https://docs.haskellstack.org/en/stable/travis_ci/
7−#
8−# Copy these contents into the root directory of your Github project in a file
9−# named .travis.yml
10−
11−# Use new container infrastructure to enable caching
12−sudo: false
13−
14−# Do not choose a language; we provide our own build tools.
15−language: generic
16−
17−# Caching so the next build will be fast too.
18−cache:
19− directories:
20− - $HOME/.ghc
21− - $HOME/.cabal
22− - $HOME/.stack
23− - $TRAVIS_BUILD_DIR/.stack-work
24−
25−# The different configurations we want to test. We have BUILD=cabal which uses
26−# cabal-install, and BUILD=stack which uses Stack. More documentation on each
27−# of those below.
28−#
29−# We set the compiler values here to tell Travis to use a different
30−# cache file per set of arguments.
31−#
32−# If you need to have different apt packages for each combination in the
33−# matrix, you can use a line such as:
34−# addons: {apt: {packages: [libfcgi-dev,libgmp-dev]}}
35−matrix:
36− include:
37− # We grab the appropriate GHC and cabal-install versions from hvr's PPA. See:
38− # https://github.com/hvr/multi-ghc-travis
39− #- env: BUILD=cabal GHCVER=7.0.4 CABALVER=1.16 HAPPYVER=1.19.5 ALEXVER=3.1.7
40− # compiler: ": #GHC 7.0.4"
41− # addons: {apt: {packages: [cabal-install-1.16,ghc-7.0.4,happy-1.19.5,alex-3.1.7], sources: [hvr-ghc]}}
42− #- env: BUILD=cabal GHCVER=7.2.2 CABALVER=1.16 HAPPYVER=1.19.5 ALEXVER=3.1.7
43− # compiler: ": #GHC 7.2.2"
44− # addons: {apt: {packages: [cabal-install-1.16,ghc-7.2.2,happy-1.19.5,alex-3.1.7], sources: [hvr-ghc]}}
45− #- env: BUILD=cabal GHCVER=7.4.2 CABALVER=1.16 HAPPYVER=1.19.5 ALEXVER=3.1.7
46− # compiler: ": #GHC 7.4.2"
47− # addons: {apt: {packages: [cabal-install-1.16,ghc-7.4.2,happy-1.19.5,alex-3.1.7], sources: [hvr-ghc]}}
48− #- env: BUILD=cabal GHCVER=7.6.3 CABALVER=1.16 HAPPYVER=1.19.5 ALEXVER=3.1.7
49− # compiler: ": #GHC 7.6.3"
50− # addons: {apt: {packages: [cabal-install-1.16,ghc-7.6.3,happy-1.19.5,alex-3.1.7], sources: [hvr-ghc]}}
51− #- env: BUILD=cabal GHCVER=7.8.4 CABALVER=1.18 HAPPYVER=1.19.5 ALEXVER=3.1.7
52− # compiler: ": #GHC 7.8.4"
53− # addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.4,happy-1.19.5,alex-3.1.7], sources: [hvr-ghc]}}
54− #- env: BUILD=cabal GHCVER=7.10.3 CABALVER=1.22 HAPPYVER=1.19.5 ALEXVER=3.1.7
55− # compiler: ": #GHC 7.10.3"
56− # addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3,happy-1.19.5,alex-3.1.7], sources: [hvr-ghc]}}
57− - env: BUILD=cabal GHCVER=8.0.2 CABALVER=1.24 HAPPYVER=1.19.5 ALEXVER=3.1.7
58− compiler: ": #GHC 8.0.2"
59− addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2,happy-1.19.5,alex-3.1.7], sources: [hvr-ghc]}}
60− - env: BUILD=cabal GHCVER=8.2.2 CABALVER=2.0 HAPPYVER=1.19.5 ALEXVER=3.1.7
61− compiler: ": #GHC 8.2.2"
62− addons: {apt: {packages: [cabal-install-2.0,ghc-8.2.2,happy-1.19.5,alex-3.1.7], sources: [hvr-ghc]}}
63− - env: BUILD=cabal GHCVER=8.4.3 CABALVER=2.2 HAPPYVER=1.19.5 ALEXVER=3.1.7
64− compiler: ": #GHC 8.4.3"
65− addons: {apt: {packages: [cabal-install-2.2,ghc-8.4.3,happy-1.19.5,alex-3.1.7], sources: [hvr-ghc]}}
66−
67− # Build with the newest GHC and cabal-install. This is an accepted failure,
68− # see below.
69− - env: BUILD=cabal GHCVER=head CABALVER=head HAPPYVER=1.19.5 ALEXVER=3.1.7
70− compiler: ": #GHC HEAD"
71− addons: {apt: {packages: [cabal-install-head,ghc-head,happy-1.19.5,alex-3.1.7], sources: [hvr-ghc]}}
72−
73− # The Stack builds. We can pass in arbitrary Stack arguments via the ARGS
74− # variable, such as using --stack-yaml to point to a different file.
75− - env: BUILD=stack ARGS=""
76− compiler: ": #stack default"
77− addons: {apt: {packages: [libgmp-dev]}}
78−
79− #- env: BUILD=stack ARGS="--resolver lts-2"
80− # compiler: ": #stack 7.8.4"
81− # addons: {apt: {packages: [libgmp-dev]}}
82−
83− #- env: BUILD=stack ARGS="--resolver lts-3"
84− # compiler: ": #stack 7.10.2"
85− # addons: {apt: {packages: [libgmp-dev]}}
86−
87− #- env: BUILD=stack ARGS="--resolver lts-6"
88− # compiler: ": #stack 7.10.3"
89− # addons: {apt: {packages: [libgmp-dev]}}
90−
91− #- env: BUILD=stack ARGS="--resolver lts-7"
92− # compiler: ": #stack 8.0.1"
93− # addons: {apt: {packages: [libgmp-dev]}}
94−
95− - env: BUILD=stack ARGS="--resolver lts-9"
96− compiler: ": #stack 8.0.2"
97− addons: {apt: {packages: [libgmp-dev]}}
98−
99− - env: BUILD=stack ARGS="--resolver lts-11"
100− compiler: ": #stack 8.2.2"
101− addons: {apt: {packages: [libgmp-dev]}}
102−
103− # Nightly builds are allowed to fail
104− - env: BUILD=stack ARGS="--resolver nightly"
105− compiler: ": #stack nightly"
106− addons: {apt: {packages: [libgmp-dev]}}
107−
108− # Build on macOS in addition to Linux
109− - env: BUILD=stack ARGS=""
110− compiler: ": #stack default osx"
111− os: osx
112−
113− # Travis includes an macOS which is incompatible with GHC 7.8.4
114− #- env: BUILD=stack ARGS="--resolver lts-2"
115− # compiler: ": #stack 7.8.4 osx"
116− # os: osx
117−
118− #- env: BUILD=stack ARGS="--resolver lts-3"
119− # compiler: ": #stack 7.10.2 osx"
120− # os: osx
121−
122− #- env: BUILD=stack ARGS="--resolver lts-6"
123− # compiler: ": #stack 7.10.3 osx"
124− # os: osx
125−
126− #- env: BUILD=stack ARGS="--resolver lts-7"
127− # compiler: ": #stack 8.0.1 osx"
128− # os: osx
129−
130− - env: BUILD=stack ARGS="--resolver lts-9"
131− compiler: ": #stack 8.0.2 osx"
132− os: osx
133−
134− - env: BUILD=stack ARGS="--resolver lts-11"
135− compiler: ": #stack 8.2.2 osx"
136− os: osx
137−
138− - env: BUILD=stack ARGS="--resolver nightly"
139− compiler: ": #stack nightly osx"
140− os: osx
141−
142− allow_failures:
143− - env: BUILD=cabal GHCVER=head CABALVER=head HAPPYVER=1.19.5 ALEXVER=3.1.7
144− - env: BUILD=stack ARGS="--resolver nightly"
145−
146−before_install:
147−# Using compiler above sets CC to an invalid value, so unset it
148−- unset CC
149−
150−# We want to always allow newer versions of packages when building on GHC HEAD
151−- CABALARGS=""
152−- if [ "x$GHCVER" = "xhead" ]; then CABALARGS=--allow-newer; fi
153−
154−# Download and unpack the stack executable
155−- export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$HOME/.local/bin:/opt/alex/$ALEXVER/bin:/opt/happy/$HAPPYVER/bin:$HOME/.cabal/bin:$PATH
156−- mkdir -p ~/.local/bin
157−- |
158− if [ `uname` = "Darwin" ]
159− then
160− travis_retry curl --insecure -L https://get.haskellstack.org/stable/osx-x86_64.tar.gz | tar xz --strip-components=1 --include '*/stack' -C ~/.local/bin
161− else
162− travis_retry curl -L https://get.haskellstack.org/stable/linux-x86_64.tar.gz | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
163− fi
164−
165− # Use the more reliable S3 mirror of Hackage
166− mkdir -p $HOME/.cabal
167− echo 'remote-repo: hackage.haskell.org:http://hackage.fpcomplete.com/' > $HOME/.cabal/config
168− echo 'remote-repo-cache: $HOME/.cabal/packages' >> $HOME/.cabal/config
169−
170−
171−install:
172−- echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
173−- if [ -f configure.ac ]; then autoreconf -i; fi
174−- |
175− set -ex
176− case "$BUILD" in
177− stack)
178− # Add in extra-deps for older snapshots, as necessary
179− stack --no-terminal --install-ghc $ARGS test --bench --dry-run || ( \
180− stack --no-terminal $ARGS build cabal-install && \
181− stack --no-terminal $ARGS solver --update-config)
182−
183− # Build the dependencies
184− stack --no-terminal --install-ghc $ARGS test --bench --only-dependencies
185− ;;
186− cabal)
187− cabal --version
188− travis_retry cabal update
189−
190− # Get the list of packages from the stack.yaml file. Note that
191− # this will also implicitly run hpack as necessary to generate
192− # the .cabal files needed by cabal-install.
193− PACKAGES=$(stack --install-ghc query locals | grep '^ *path' | sed 's@^ *path:@@')
194−
195− cabal install --only-dependencies --enable-tests --enable-benchmarks --force-reinstalls --ghc-options=-O0 --reorder-goals --max-backjumps=-1 $CABALARGS $PACKAGES
196− ;;
197− esac
198− set +ex
199−
200−script:
201−- |
202− set -ex
203− case "$BUILD" in
204− stack)
205− stack --no-terminal $ARGS test --bench --no-run-benchmarks --haddock --no-haddock-deps
206− ;;
207− cabal)
208− cabal install --enable-tests --enable-benchmarks --force-reinstalls --ghc-options=-O0 --reorder-goals --max-backjumps=-1 $CABALARGS $PACKAGES
209−
210− ORIGDIR=$(pwd)
211− for dir in $PACKAGES
212− do
213− cd $dir
214− cabal check || [ "$CABALVER" == "1.16" ]
215− cabal sdist
216− PKGVER=$(cabal info . | awk '{print $2;exit}')
217− SRC_TGZ=$PKGVER.tar.gz
218− cd dist
219− tar zxfv "$SRC_TGZ"
220− cd "$PKGVER"
221− cabal configure --enable-tests --ghc-options -O0
222− cabal build
223− if [ "$CABALVER" = "1.16" ] || [ "$CABALVER" = "1.18" ]; then
224− cabal test
225− else
226− cabal test --show-details=streaming --log=/dev/stdout
227− fi
228− cd $ORIGDIR
229− done
230− ;;
231− esac
232− set +ex
README.md+15−12
@@ -1,20 +1,23 @@
1−## yaml
1+# YAML Haskell Library
2
2
3−[![Build Status](https://travis-ci.org/snoyberg/yaml.svg?branch=master)](https://travis-ci.org/snoyberg/yaml)
3+[![Build Status](https://dev.azure.com/snoyberg/yaml/_apis/build/status/snoyberg.yaml?branchName=master)](https://dev.azure.com/snoyberg/yaml/_build/latest?definitionId=7&branchName=master)
4−[![Build status](https://ci.appveyor.com/api/projects/status/hqy2jketp8m502so/branch/master?svg=true)](https://ci.appveyor.com/project/snoyberg/yaml/branch/master)
5
4
6−Provides support for parsing and emitting Yaml documents.
5+This project contains two haskell packages: `yaml` for higher-level parsing and writing of yaml documents, and `libyaml`
6+for lower-level event-based streaming.
7
7
8−This package includes the [full libyaml C library version 0.2.1 by Kirill Simonov](https://github.com/yaml/libyaml) in the package so you don't need to worry about any non-Haskell dependencies.
8+## `yaml` Package
9
9
10−The package is broken down into two primary modules. `Data.Yaml` provides a high-level interface based around the JSON datatypes provided by the `aeson` package. `Text.Libyaml` provides a lower-level, streaming interface. For most users, `Data.Yaml` is recommended.
10+`yaml` provides a high-level interface based around the JSON datatypes provided by the `aeson` package. This allows
11+using JSON and YAML interchangeably in your code with the `aeson` typeclasses. See the
12+[yaml README](https://github.com/snoyberg/yaml/tree/master/yaml/README.md) for more details.
11
13
12−### Examples
14+## `libyaml` Package
13
15
14−Usage examples can be found in the `Data.Yaml` documentation or in the [examples](https://github.com/snoyberg/yaml/tree/master/examples) directory.
16+`libyaml` is a wrapper over the libyaml C library (and includes the source so no external library is needed). It is an
17+event-based streaming API. See the [libyaml README](https://github.com/snoyberg/yaml/tree/master/libyaml/README.md) for
18+more details.
15
19
16−### Additional modules
20+## License
17
21
18−* `Data.Yaml.Include` supports adding `!include` directives to your YAML files.
22+This project is licensed with the BSD 3-Clause license. Copies of the license can be found in both the `yaml` and
19−* `Data.Yaml.Builder` and `Data.Yaml.Parser` allow more fine-grained control of parsing an rendering, as opposed to just using the aeson typeclass and datatype system for parsing and rendering.
23+`libyaml` subdirectories
20−* `Data.Yaml.Aeson` is currently a re-export of `Data.Yaml` to explicitly choose to use the aeson-compatible API.
appveyor.ymldeleted−32
@@ -1,32 +0,0 @@
1−build: off
2−
3−before_test:
4−# http://help.appveyor.com/discussions/problems/6312-curl-command-not-found
5−- set PATH=C:\Program Files\Git\mingw64\bin;%PATH%
6−
7−- curl -sS -ostack.zip -L --insecure https://get.haskellstack.org/stable/windows-x86_64.zip
8−- 7z x stack.zip stack.exe
9−
10−clone_folder: "c:\\stack"
11−environment:
12− global:
13− STACK_ROOT: "c:\\sr"
14−
15− matrix:
16− - ARGS: ""
17− #- ARGS: "--resolver lts-2"
18− #- ARGS: "--resolver lts-3"
19− #- ARGS: "--resolver lts-6"
20− #- ARGS: "--resolver lts-7"
21− - ARGS: "--resolver lts-9"
22− - ARGS: "--resolver lts-11"
23− #- ARGS: "--resolver nightly"
24−
25−test_script:
26−
27−# Install toolchain, but do it silently due to lots of output
28−- stack %ARGS% setup > nul
29−
30−# The ugly echo "" hack is to avoid complaints about 0 being an invalid file
31−# descriptor
32−- echo "" | stack %ARGS% --no-terminal test
copy-libyaml.shdeleted−10
@@ -1,10 +0,0 @@
1−#!/usr/bin/env bash
2−
3−set -ex
4−
5−rm -rf libyaml
6−mkdir -p libyaml
7−cp vendor/libyaml/LICENSE libyaml
8−cp vendor/libyaml/src/*.c libyaml
9−cp vendor/libyaml/src/*.h libyaml
10−cp vendor/libyaml/include/*.h libyaml
exe/json2yaml.hsdeleted−22
@@ -1,22 +0,0 @@
1−import qualified Data.Aeson as J
2−import qualified Data.ByteString as S
3−import qualified Data.ByteString.Lazy as L
4−import System.Environment (getArgs)
5−
6−import qualified Data.Yaml as Y
7−
8−main :: IO ()
9−main = do
10− args <- getArgs
11− (input, output) <- case args ++ replicate (2 - length args) "-" of
12− [i, o] -> return (i, o)
13− _ -> fail "Usage: json2yaml [in] [out]"
14− mval <- fmap J.decode $
15− case input of
16− "-" -> L.getContents
17− _ -> L.readFile input
18− case mval of
19− Nothing -> error "Invalid input JSON"
20− Just val -> case output of
21− "-" -> S.putStr $ Y.encode (val :: Y.Value)
22− _ -> Y.encodeFile output val
exe/yaml2json.hsdeleted−31
@@ -1,31 +0,0 @@
1−import Prelude hiding (putStr, getContents)
2−
3−import Data.Aeson (encode, Value)
4−import Data.ByteString (getContents)
5−import Data.ByteString.Lazy (putStr)
6−import System.Environment (getArgs)
7−import System.Exit
8−import System.IO (stderr, hPutStrLn)
9−
10−import Data.Yaml (decodeFileEither, decodeEither')
11−
12−helpMessage :: IO ()
13−helpMessage = putStrLn "Usage: yaml2json FILE\n\nuse '-' as FILE to indicate stdin" >> exitFailure
14−
15−showJSON :: Show a => Either a Value -> IO b
16−showJSON ejson =
17− case ejson of
18− Left err -> hPutStrLn stderr (show err) >> exitFailure
19− Right res -> putStr (encode (res :: Value)) >> exitSuccess
20−
21−main :: IO ()
22−main = do
23− args <- getArgs
24− case args of
25− -- strict getContents will read in all of stdin at once
26− (["-h"]) -> helpMessage
27− (["--help"]) -> helpMessage
28− (["-"]) -> getContents >>= showJSON . decodeEither'
29− ([f]) -> decodeFileEither f >>= showJSON
30− _ -> helpMessage
31−
libyaml/ChangeLog.mdnew file+27
@@ -0,0 +1,27 @@
1+# Changelog for libyaml
2+
3+## 0.1.4
4+
5+* Use libyaml-clib for the cbits
6+* Use pkg-config to link to system yaml
7+
8+## 0.1.3
9+
10+* Correct signature for `fclose`
11+
12+## 0.1.2
13+
14+* Upgrade `libyaml` to 0.2.2
15+
16+## 0.1.1.1
17+
18+* Work around GHC 8.6.5 issue on Windows preventing truncated files. [#178](https://github.com/snoyberg/yaml/issues/178)
19+
20+## 0.1.1.0
21+
22+* Add options to `FormatOptions` to govern when tags rendered explicitly and when they are left implicit. [#165](https://github.com/snoyberg/yaml/issues/165)
23+
24+## 0.1.0.0
25+
26+* Split `libyaml` into a separate package from `yaml`. This split occurred at
27+ `yaml` version 0.10.4.0.
libyaml/LICENSE+22−17
@@ -1,20 +1,25 @@
1−Copyright (c) 2017-2018 Ingy döt Net
1+The following license covers this documentation, and the source code, except
2−Copyright (c) 2006-2016 Kirill Simonov
2+where otherwise indicated.
3
3
4−Permission is hereby granted, free of charge, to any person obtaining a copy of
4+Copyright 2008, Michael Snoyman. All rights reserved.
5−this software and associated documentation files (the "Software"), to deal in
6−the Software without restriction, including without limitation the rights to
7−use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
8−of the Software, and to permit persons to whom the Software is furnished to do
9−so, subject to the following conditions:
10
5
11−The above copyright notice and this permission notice shall be included in all
6+Redistribution and use in source and binary forms, with or without
12−copies or substantial portions of the Software.
7+modification, are permitted provided that the following conditions are met:
13
8
9+* Redistributions of source code must retain the above copyright notice, this
10+ list of conditions and the following disclaimer.
11+
12+* Redistributions in binary form must reproduce the above copyright notice,
13+ this list of conditions and the following disclaimer in the documentation
14+ and/or other materials provided with the distribution.
15+
14−THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR
15−IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16−FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
17−AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
20+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22+OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18−LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
19−OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
20−SOFTWARE.
25+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Makefile → libyaml/Makefilerenamed

The content is the same.

libyaml/README.mdnew file+3
@@ -0,0 +1,3 @@
1+# libyaml
2+
3+This package provides a haskell wrapper over the [libyaml C library version 0.2.2 by Kirill Simonov](https://github.com/yaml/libyaml). It contains the C source so you don't need to worry about any non-Haskell dependencies.
libyaml/Setup.hsnew file+2
@@ -0,0 +1,2 @@
1+import Distribution.Simple
2+main = defaultMain
libyaml/api.cdeleted−1402
@@ -1,1402 +0,0 @@
1−
2−#include "yaml_private.h"
3−
4−/*
5− * Get the library version.
6− */
7−
8−YAML_DECLARE(const char *)
9−yaml_get_version_string(void)
10−{
11− return YAML_VERSION_STRING;
12−}
13−
14−/*
15− * Get the library version numbers.
16− */
17−
18−YAML_DECLARE(void)
19−yaml_get_version(int *major, int *minor, int *patch)
20−{
21− *major = YAML_VERSION_MAJOR;
22− *minor = YAML_VERSION_MINOR;
23− *patch = YAML_VERSION_PATCH;
24−}
25−
26−/*
27− * Allocate a dynamic memory block.
28− */
29−
30−YAML_DECLARE(void *)
31−yaml_malloc(size_t size)
32−{
33− return malloc(size ? size : 1);
34−}
35−
36−/*
37− * Reallocate a dynamic memory block.
38− */
39−
40−YAML_DECLARE(void *)
41−yaml_realloc(void *ptr, size_t size)
42−{
43− return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1);
44−}
45−
46−/*
47− * Free a dynamic memory block.
48− */
49−
50−YAML_DECLARE(void)
51−yaml_free(void *ptr)
52−{
53− if (ptr) free(ptr);
54−}
55−
56−/*
57− * Duplicate a string.
58− */
59−
60−YAML_DECLARE(yaml_char_t *)
61−yaml_strdup(const yaml_char_t *str)
62−{
63− if (!str)
64− return NULL;
65−
66−/*
67− * Haskell yaml package: added to support _WIN64
68− */
69−#if _WIN64
70− return (yaml_char_t *)_strdup((char *)str);
71−#else
72− return (yaml_char_t *)strdup((char *)str);
73−#endif
74−}
75−
76−/*
77− * Extend a string.
78− */
79−
80−YAML_DECLARE(int)
81−yaml_string_extend(yaml_char_t **start,
82− yaml_char_t **pointer, yaml_char_t **end)
83−{
84− yaml_char_t *new_start = (yaml_char_t *)yaml_realloc((void*)*start, (*end - *start)*2);
85−
86− if (!new_start) return 0;
87−
88− memset(new_start + (*end - *start), 0, *end - *start);
89−
90− *pointer = new_start + (*pointer - *start);
91− *end = new_start + (*end - *start)*2;
92− *start = new_start;
93−
94− return 1;
95−}
96−
97−/*
98− * Append a string B to a string A.
99− */
100−
101−YAML_DECLARE(int)
102−yaml_string_join(
103− yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
104− yaml_char_t **b_start, yaml_char_t **b_pointer, SHIM(yaml_char_t **b_end))
105−{
106− UNUSED_PARAM(b_end)
107− if (*b_start == *b_pointer)
108− return 1;
109−
110− while (*a_end - *a_pointer <= *b_pointer - *b_start) {
111− if (!yaml_string_extend(a_start, a_pointer, a_end))
112− return 0;
113− }
114−
115− memcpy(*a_pointer, *b_start, *b_pointer - *b_start);
116− *a_pointer += *b_pointer - *b_start;
117−
118− return 1;
119−}
120−
121−/*
122− * Extend a stack.
123− */
124−
125−YAML_DECLARE(int)
126−yaml_stack_extend(void **start, void **top, void **end)
127−{
128− void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2);
129−
130− if (!new_start) return 0;
131−
132− *top = (char *)new_start + ((char *)*top - (char *)*start);
133− *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
134− *start = new_start;
135−
136− return 1;
137−}
138−
139−/*
140− * Extend or move a queue.
141− */
142−
143−YAML_DECLARE(int)
144−yaml_queue_extend(void **start, void **head, void **tail, void **end)
145−{
146− /* Check if we need to resize the queue. */
147−
148− if (*start == *head && *tail == *end) {
149− void *new_start = yaml_realloc(*start,
150− ((char *)*end - (char *)*start)*2);
151−
152− if (!new_start) return 0;
153−
154− *head = (char *)new_start + ((char *)*head - (char *)*start);
155− *tail = (char *)new_start + ((char *)*tail - (char *)*start);
156− *end = (char *)new_start + ((char *)*end - (char *)*start)*2;
157− *start = new_start;
158− }
159−
160− /* Check if we need to move the queue at the beginning of the buffer. */
161−
162− if (*tail == *end) {
163− if (*head != *tail) {
164− memmove(*start, *head, (char *)*tail - (char *)*head);
165− }
166− *tail = (char *)*tail - (char *)*head + (char *)*start;
167− *head = *start;
168− }
169−
170− return 1;
171−}
172−
173−
174−/*
175− * Create a new parser object.
176− */
177−
178−YAML_DECLARE(int)
179−yaml_parser_initialize(yaml_parser_t *parser)
180−{
181− assert(parser); /* Non-NULL parser object expected. */
182−
183− memset(parser, 0, sizeof(yaml_parser_t));
184− if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE))
185− goto error;
186− if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE))
187− goto error;
188− if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE, yaml_token_t*))
189− goto error;
190− if (!STACK_INIT(parser, parser->indents, int*))
191− goto error;
192− if (!STACK_INIT(parser, parser->simple_keys, yaml_simple_key_t*))
193− goto error;
194− if (!STACK_INIT(parser, parser->states, yaml_parser_state_t*))
195− goto error;
196− if (!STACK_INIT(parser, parser->marks, yaml_mark_t*))
197− goto error;
198− if (!STACK_INIT(parser, parser->tag_directives, yaml_tag_directive_t*))
199− goto error;
200−
201− return 1;
202−
203−error:
204−
205− BUFFER_DEL(parser, parser->raw_buffer);
206− BUFFER_DEL(parser, parser->buffer);
207− QUEUE_DEL(parser, parser->tokens);
208− STACK_DEL(parser, parser->indents);
209− STACK_DEL(parser, parser->simple_keys);
210− STACK_DEL(parser, parser->states);
211− STACK_DEL(parser, parser->marks);
212− STACK_DEL(parser, parser->tag_directives);
213−
214− return 0;
215−}
216−
217−/*
218− * Destroy a parser object.
219− */
220−
221−YAML_DECLARE(void)
222−yaml_parser_delete(yaml_parser_t *parser)
223−{
224− assert(parser); /* Non-NULL parser object expected. */
225−
226− BUFFER_DEL(parser, parser->raw_buffer);
227− BUFFER_DEL(parser, parser->buffer);
228− while (!QUEUE_EMPTY(parser, parser->tokens)) {
229− yaml_token_delete(&DEQUEUE(parser, parser->tokens));
230− }
231− QUEUE_DEL(parser, parser->tokens);
232− STACK_DEL(parser, parser->indents);
233− STACK_DEL(parser, parser->simple_keys);
234− STACK_DEL(parser, parser->states);
235− STACK_DEL(parser, parser->marks);
236− while (!STACK_EMPTY(parser, parser->tag_directives)) {
237− yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
238− yaml_free(tag_directive.handle);
239− yaml_free(tag_directive.prefix);
240− }
241− STACK_DEL(parser, parser->tag_directives);
242−
243− memset(parser, 0, sizeof(yaml_parser_t));
244−}
245−
246−/*
247− * String read handler.
248− */
249−
250−static int
251−yaml_string_read_handler(void *data, unsigned char *buffer, size_t size,
252− size_t *size_read)
253−{
254− yaml_parser_t *parser = (yaml_parser_t *)data;
255−
256− if (parser->input.string.current == parser->input.string.end) {
257− *size_read = 0;
258− return 1;
259− }
260−
261− if (size > (size_t)(parser->input.string.end
262− - parser->input.string.current)) {
263− size = parser->input.string.end - parser->input.string.current;
264− }
265−
266− memcpy(buffer, parser->input.string.current, size);
267− parser->input.string.current += size;
268− *size_read = size;
269− return 1;
270−}
271−
272−/*
273− * File read handler.
274− */
275−
276−static int
277−yaml_file_read_handler(void *data, unsigned char *buffer, size_t size,
278− size_t *size_read)
279−{
280− yaml_parser_t *parser = (yaml_parser_t *)data;
281−
282− *size_read = fread(buffer, 1, size, parser->input.file);
283− return !ferror(parser->input.file);
284−}
285−
286−/*
287− * Set a string input.
288− */
289−
290−YAML_DECLARE(void)
291−yaml_parser_set_input_string(yaml_parser_t *parser,
292− const unsigned char *input, size_t size)
293−{
294− assert(parser); /* Non-NULL parser object expected. */
295− assert(!parser->read_handler); /* You can set the source only once. */
296− assert(input); /* Non-NULL input string expected. */
297−
298− parser->read_handler = yaml_string_read_handler;
299− parser->read_handler_data = parser;
300−
301− parser->input.string.start = input;
302− parser->input.string.current = input;
303− parser->input.string.end = input+size;
304−}
305−
306−/*
307− * Set a file input.
308− */
309−
310−YAML_DECLARE(void)
311−yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file)
312−{
313− assert(parser); /* Non-NULL parser object expected. */
314− assert(!parser->read_handler); /* You can set the source only once. */
315− assert(file); /* Non-NULL file object expected. */
316−
317− parser->read_handler = yaml_file_read_handler;
318− parser->read_handler_data = parser;
319−
320− parser->input.file = file;
321−}
322−
323−/*
324− * Set a generic input.
325− */
326−
327−YAML_DECLARE(void)
328−yaml_parser_set_input(yaml_parser_t *parser,
329− yaml_read_handler_t *handler, void *data)
330−{
331− assert(parser); /* Non-NULL parser object expected. */
332− assert(!parser->read_handler); /* You can set the source only once. */
333− assert(handler); /* Non-NULL read handler expected. */
334−
335− parser->read_handler = handler;
336− parser->read_handler_data = data;
337−}
338−
339−/*
340− * Set the source encoding.
341− */
342−
343−YAML_DECLARE(void)
344−yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding)
345−{
346− assert(parser); /* Non-NULL parser object expected. */
347− assert(!parser->encoding); /* Encoding is already set or detected. */
348−
349− parser->encoding = encoding;
350−}
351−
352−/*
353− * Create a new emitter object.
354− */
355−
356−YAML_DECLARE(int)
357−yaml_emitter_initialize(yaml_emitter_t *emitter)
358−{
359− assert(emitter); /* Non-NULL emitter object expected. */
360−
361− memset(emitter, 0, sizeof(yaml_emitter_t));
362− if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE))
363− goto error;
364− if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE))
365− goto error;
366− if (!STACK_INIT(emitter, emitter->states, yaml_emitter_state_t*))
367− goto error;
368− if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE, yaml_event_t*))
369− goto error;
370− if (!STACK_INIT(emitter, emitter->indents, int*))
371− goto error;
372− if (!STACK_INIT(emitter, emitter->tag_directives, yaml_tag_directive_t*))
373− goto error;
374−
375− return 1;
376−
377−error:
378−
379− BUFFER_DEL(emitter, emitter->buffer);
380− BUFFER_DEL(emitter, emitter->raw_buffer);
381− STACK_DEL(emitter, emitter->states);
382− QUEUE_DEL(emitter, emitter->events);
383− STACK_DEL(emitter, emitter->indents);
384− STACK_DEL(emitter, emitter->tag_directives);
385−
386− return 0;
387−}
388−
389−/*
390− * Destroy an emitter object.
391− */
392−
393−YAML_DECLARE(void)
394−yaml_emitter_delete(yaml_emitter_t *emitter)
395−{
396− assert(emitter); /* Non-NULL emitter object expected. */
397−
398− BUFFER_DEL(emitter, emitter->buffer);
399− BUFFER_DEL(emitter, emitter->raw_buffer);
400− STACK_DEL(emitter, emitter->states);
401− while (!QUEUE_EMPTY(emitter, emitter->events)) {
402− yaml_event_delete(&DEQUEUE(emitter, emitter->events));
403− }
404− QUEUE_DEL(emitter, emitter->events);
405− STACK_DEL(emitter, emitter->indents);
406− while (!STACK_EMPTY(empty, emitter->tag_directives)) {
407− yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives);
408− yaml_free(tag_directive.handle);
409− yaml_free(tag_directive.prefix);
410− }
411− STACK_DEL(emitter, emitter->tag_directives);
412− yaml_free(emitter->anchors);
413−
414− memset(emitter, 0, sizeof(yaml_emitter_t));
415−}
416−
417−/*
418− * String write handler.
419− */
420−
421−static int
422−yaml_string_write_handler(void *data, unsigned char *buffer, size_t size)
423−{
424− yaml_emitter_t *emitter = (yaml_emitter_t *)data;
425−
426− if (emitter->output.string.size - *emitter->output.string.size_written
427− < size) {
428− memcpy(emitter->output.string.buffer
429− + *emitter->output.string.size_written,
430− buffer,
431− emitter->output.string.size
432− - *emitter->output.string.size_written);
433− *emitter->output.string.size_written = emitter->output.string.size;
434− return 0;
435− }
436−
437− memcpy(emitter->output.string.buffer
438− + *emitter->output.string.size_written, buffer, size);
439− *emitter->output.string.size_written += size;
440− return 1;
441−}
442−
443−/*
444− * File write handler.
445− */
446−
447−static int
448−yaml_file_write_handler(void *data, unsigned char *buffer, size_t size)
449−{
450− yaml_emitter_t *emitter = (yaml_emitter_t *)data;
451−
452− return (fwrite(buffer, 1, size, emitter->output.file) == size);
453−}
454−/*
455− * Set a string output.
456− */
457−
458−YAML_DECLARE(void)
459−yaml_emitter_set_output_string(yaml_emitter_t *emitter,
460− unsigned char *output, size_t size, size_t *size_written)
461−{
462− assert(emitter); /* Non-NULL emitter object expected. */
463− assert(!emitter->write_handler); /* You can set the output only once. */
464− assert(output); /* Non-NULL output string expected. */
465−
466− emitter->write_handler = yaml_string_write_handler;
467− emitter->write_handler_data = emitter;
468−
469− emitter->output.string.buffer = output;
470− emitter->output.string.size = size;
471− emitter->output.string.size_written = size_written;
472− *size_written = 0;
473−}
474−
475−/*
476− * Set a file output.
477− */
478−
479−YAML_DECLARE(void)
480−yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file)
481−{
482− assert(emitter); /* Non-NULL emitter object expected. */
483− assert(!emitter->write_handler); /* You can set the output only once. */
484− assert(file); /* Non-NULL file object expected. */
485−
486− emitter->write_handler = yaml_file_write_handler;
487− emitter->write_handler_data = emitter;
488−
489− emitter->output.file = file;
490−}
491−
492−/*
493− * Set a generic output handler.
494− */
495−
496−YAML_DECLARE(void)
497−yaml_emitter_set_output(yaml_emitter_t *emitter,
498− yaml_write_handler_t *handler, void *data)
499−{
500− assert(emitter); /* Non-NULL emitter object expected. */
501− assert(!emitter->write_handler); /* You can set the output only once. */
502− assert(handler); /* Non-NULL handler object expected. */
503−
504− emitter->write_handler = handler;
505− emitter->write_handler_data = data;
506−}
507−
508−/*
509− * Set the output encoding.
510− */
511−
512−YAML_DECLARE(void)
513−yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding)
514−{
515− assert(emitter); /* Non-NULL emitter object expected. */
516− assert(!emitter->encoding); /* You can set encoding only once. */
517−
518− emitter->encoding = encoding;
519−}
520−
521−/*
522− * Set the canonical output style.
523− */
524−
525−YAML_DECLARE(void)
526−yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical)
527−{
528− assert(emitter); /* Non-NULL emitter object expected. */
529−
530− emitter->canonical = (canonical != 0);
531−}
532−
533−/*
534− * Set the indentation increment.
535− */
536−
537−YAML_DECLARE(void)
538−yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent)
539−{
540− assert(emitter); /* Non-NULL emitter object expected. */
541−
542− emitter->best_indent = (1 < indent && indent < 10) ? indent : 2;
543−}
544−
545−/*
546− * Set the preferred line width.
547− */
548−
549−YAML_DECLARE(void)
550−yaml_emitter_set_width(yaml_emitter_t *emitter, int width)
551−{
552− assert(emitter); /* Non-NULL emitter object expected. */
553−
554− emitter->best_width = (width >= 0) ? width : -1;
555−}
556−
557−/*
558− * Set if unescaped non-ASCII characters are allowed.
559− */
560−
561−YAML_DECLARE(void)
562−yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode)
563−{
564− assert(emitter); /* Non-NULL emitter object expected. */
565−
566− emitter->unicode = (unicode != 0);
567−}
568−
569−/*
570− * Set the preferred line break character.
571− */
572−
573−YAML_DECLARE(void)
574−yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break)
575−{
576− assert(emitter); /* Non-NULL emitter object expected. */
577−
578− emitter->line_break = line_break;
579−}
580−
581−/*
582− * Destroy a token object.
583− */
584−
585−YAML_DECLARE(void)
586−yaml_token_delete(yaml_token_t *token)
587−{
588− assert(token); /* Non-NULL token object expected. */
589−
590− switch (token->type)
591− {
592− case YAML_TAG_DIRECTIVE_TOKEN:
593− yaml_free(token->data.tag_directive.handle);
594− yaml_free(token->data.tag_directive.prefix);
595− break;
596−
597− case YAML_ALIAS_TOKEN:
598− yaml_free(token->data.alias.value);
599− break;
600−
601− case YAML_ANCHOR_TOKEN:
602− yaml_free(token->data.anchor.value);
603− break;
604−
605− case YAML_TAG_TOKEN:
606− yaml_free(token->data.tag.handle);
607− yaml_free(token->data.tag.suffix);
608− break;
609−
610− case YAML_SCALAR_TOKEN:
611− yaml_free(token->data.scalar.value);
612− break;
613−
614− default:
615− break;
616− }
617−
618− memset(token, 0, sizeof(yaml_token_t));
619−}
620−
621−/*
622− * Check if a string is a valid UTF-8 sequence.
623− *
624− * Check 'reader.c' for more details on UTF-8 encoding.
625− */
626−
627−static int
628−yaml_check_utf8(yaml_char_t *start, size_t length)
629−{
630− yaml_char_t *end = start+length;
631− yaml_char_t *pointer = start;
632−
633− while (pointer < end) {
634− unsigned char octet;
635− unsigned int width;
636− unsigned int value;
637− size_t k;
638−
639− octet = pointer[0];
640− width = (octet & 0x80) == 0x00 ? 1 :
641− (octet & 0xE0) == 0xC0 ? 2 :
642− (octet & 0xF0) == 0xE0 ? 3 :
643− (octet & 0xF8) == 0xF0 ? 4 : 0;
644− value = (octet & 0x80) == 0x00 ? octet & 0x7F :
645− (octet & 0xE0) == 0xC0 ? octet & 0x1F :
646− (octet & 0xF0) == 0xE0 ? octet & 0x0F :
647− (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
648− if (!width) return 0;
649− if (pointer+width > end) return 0;
650− for (k = 1; k < width; k ++) {
651− octet = pointer[k];
652− if ((octet & 0xC0) != 0x80) return 0;
653− value = (value << 6) + (octet & 0x3F);
654− }
655− if (!((width == 1) ||
656− (width == 2 && value >= 0x80) ||
657− (width == 3 && value >= 0x800) ||
658− (width == 4 && value >= 0x10000))) return 0;
659−
660− pointer += width;
661− }
662−
663− return 1;
664−}
665−
666−/*
667− * Create STREAM-START.
668− */
669−
670−YAML_DECLARE(int)
671−yaml_stream_start_event_initialize(yaml_event_t *event,
672− yaml_encoding_t encoding)
673−{
674− yaml_mark_t mark = { 0, 0, 0 };
675−
676− assert(event); /* Non-NULL event object is expected. */
677−
678− STREAM_START_EVENT_INIT(*event, encoding, mark, mark);
679−
680− return 1;
681−}
682−
683−/*
684− * Create STREAM-END.
685− */
686−
687−YAML_DECLARE(int)
688−yaml_stream_end_event_initialize(yaml_event_t *event)
689−{
690− yaml_mark_t mark = { 0, 0, 0 };
691−
692− assert(event); /* Non-NULL event object is expected. */
693−
694− STREAM_END_EVENT_INIT(*event, mark, mark);
695−
696− return 1;
697−}
698−
699−/*
700− * Create DOCUMENT-START.
701− */
702−
703−YAML_DECLARE(int)
704−yaml_document_start_event_initialize(yaml_event_t *event,
705− yaml_version_directive_t *version_directive,
706− yaml_tag_directive_t *tag_directives_start,
707− yaml_tag_directive_t *tag_directives_end,
708− int implicit)
709−{
710− struct {
711− yaml_error_type_t error;
712− } context;
713− yaml_mark_t mark = { 0, 0, 0 };
714− yaml_version_directive_t *version_directive_copy = NULL;
715− struct {
716− yaml_tag_directive_t *start;
717− yaml_tag_directive_t *end;
718− yaml_tag_directive_t *top;
719− } tag_directives_copy = { NULL, NULL, NULL };
720− yaml_tag_directive_t value = { NULL, NULL };
721−
722− assert(event); /* Non-NULL event object is expected. */
723− assert((tag_directives_start && tag_directives_end) ||
724− (tag_directives_start == tag_directives_end));
725− /* Valid tag directives are expected. */
726−
727− if (version_directive) {
728− version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t);
729− if (!version_directive_copy) goto error;
730− version_directive_copy->major = version_directive->major;
731− version_directive_copy->minor = version_directive->minor;
732− }
733−
734− if (tag_directives_start != tag_directives_end) {
735− yaml_tag_directive_t *tag_directive;
736− if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*))
737− goto error;
738− for (tag_directive = tag_directives_start;
739− tag_directive != tag_directives_end; tag_directive ++) {
740− assert(tag_directive->handle);
741− assert(tag_directive->prefix);
742− if (!yaml_check_utf8(tag_directive->handle,
743− strlen((char *)tag_directive->handle)))
744− goto error;
745− if (!yaml_check_utf8(tag_directive->prefix,
746− strlen((char *)tag_directive->prefix)))
747− goto error;
748− value.handle = yaml_strdup(tag_directive->handle);
749− value.prefix = yaml_strdup(tag_directive->prefix);
750− if (!value.handle || !value.prefix) goto error;
751− if (!PUSH(&context, tag_directives_copy, value))
752− goto error;
753− value.handle = NULL;
754− value.prefix = NULL;
755− }
756− }
757−
758− DOCUMENT_START_EVENT_INIT(*event, version_directive_copy,
759− tag_directives_copy.start, tag_directives_copy.top,
760− implicit, mark, mark);
761−
762− return 1;
763−
764−error:
765− yaml_free(version_directive_copy);
766− while (!STACK_EMPTY(context, tag_directives_copy)) {
767− yaml_tag_directive_t value = POP(context, tag_directives_copy);
768− yaml_free(value.handle);
769− yaml_free(value.prefix);
770− }
771− STACK_DEL(context, tag_directives_copy);
772− yaml_free(value.handle);
773− yaml_free(value.prefix);
774−
775− return 0;
776−}
777−
778−/*
779− * Create DOCUMENT-END.
780− */
781−
782−YAML_DECLARE(int)
783−yaml_document_end_event_initialize(yaml_event_t *event, int implicit)
784−{
785− yaml_mark_t mark = { 0, 0, 0 };
786−
787− assert(event); /* Non-NULL emitter object is expected. */
788−
789− DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark);
790−
791− return 1;
792−}
793−
794−/*
795− * Create ALIAS.
796− */
797−
798−YAML_DECLARE(int)
799−yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor)
800−{
801− yaml_mark_t mark = { 0, 0, 0 };
802− yaml_char_t *anchor_copy = NULL;
803−
804− assert(event); /* Non-NULL event object is expected. */
805− assert(anchor); /* Non-NULL anchor is expected. */
806−
807− if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0;
808−
809− anchor_copy = yaml_strdup(anchor);
810− if (!anchor_copy)
811− return 0;
812−
813− ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark);
814−
815− return 1;
816−}
817−
818−/*
819− * Create SCALAR.
820− */
821−
822−YAML_DECLARE(int)
823−yaml_scalar_event_initialize(yaml_event_t *event,
824− yaml_char_t *anchor, yaml_char_t *tag,
825− yaml_char_t *value, int length,
826− int plain_implicit, int quoted_implicit,
827− yaml_scalar_style_t style)
828−{
829− yaml_mark_t mark = { 0, 0, 0 };
830− yaml_char_t *anchor_copy = NULL;
831− yaml_char_t *tag_copy = NULL;
832− yaml_char_t *value_copy = NULL;
833−
834− assert(event); /* Non-NULL event object is expected. */
835− /* following line added for Haskell yaml library */
836− if (!value && !length) value = (unsigned char*)"";
837− assert(value); /* Non-NULL anchor is expected. */
838−
839− if (anchor) {
840− if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
841− anchor_copy = yaml_strdup(anchor);
842− if (!anchor_copy) goto error;
843− }
844−
845− if (tag) {
846− if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
847− tag_copy = yaml_strdup(tag);
848− if (!tag_copy) goto error;
849− }
850−
851− if (length < 0) {
852− length = strlen((char *)value);
853− }
854−
855− if (!yaml_check_utf8(value, length)) goto error;
856− value_copy = YAML_MALLOC(length+1);
857− if (!value_copy) goto error;
858− memcpy(value_copy, value, length);
859− value_copy[length] = '\0';
860−
861− SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length,
862− plain_implicit, quoted_implicit, style, mark, mark);
863−
864− return 1;
865−
866−error:
867− yaml_free(anchor_copy);
868− yaml_free(tag_copy);
869− yaml_free(value_copy);
870−
871− return 0;
872−}
873−
874−/*
875− * Create SEQUENCE-START.
876− */
877−
878−YAML_DECLARE(int)
879−yaml_sequence_start_event_initialize(yaml_event_t *event,
880− yaml_char_t *anchor, yaml_char_t *tag, int implicit,
881− yaml_sequence_style_t style)
882−{
883− yaml_mark_t mark = { 0, 0, 0 };
884− yaml_char_t *anchor_copy = NULL;
885− yaml_char_t *tag_copy = NULL;
886−
887− assert(event); /* Non-NULL event object is expected. */
888−
889− if (anchor) {
890− if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
891− anchor_copy = yaml_strdup(anchor);
892− if (!anchor_copy) goto error;
893− }
894−
895− if (tag) {
896− if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
897− tag_copy = yaml_strdup(tag);
898− if (!tag_copy) goto error;
899− }
900−
901− SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy,
902− implicit, style, mark, mark);
903−
904− return 1;
905−
906−error:
907− yaml_free(anchor_copy);
908− yaml_free(tag_copy);
909−
910− return 0;
911−}
912−
913−/*
914− * Create SEQUENCE-END.
915− */
916−
917−YAML_DECLARE(int)
918−yaml_sequence_end_event_initialize(yaml_event_t *event)
919−{
920− yaml_mark_t mark = { 0, 0, 0 };
921−
922− assert(event); /* Non-NULL event object is expected. */
923−
924− SEQUENCE_END_EVENT_INIT(*event, mark, mark);
925−
926− return 1;
927−}
928−
929−/*
930− * Create MAPPING-START.
931− */
932−
933−YAML_DECLARE(int)
934−yaml_mapping_start_event_initialize(yaml_event_t *event,
935− yaml_char_t *anchor, yaml_char_t *tag, int implicit,
936− yaml_mapping_style_t style)
937−{
938− yaml_mark_t mark = { 0, 0, 0 };
939− yaml_char_t *anchor_copy = NULL;
940− yaml_char_t *tag_copy = NULL;
941−
942− assert(event); /* Non-NULL event object is expected. */
943−
944− if (anchor) {
945− if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error;
946− anchor_copy = yaml_strdup(anchor);
947− if (!anchor_copy) goto error;
948− }
949−
950− if (tag) {
951− if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
952− tag_copy = yaml_strdup(tag);
953− if (!tag_copy) goto error;
954− }
955−
956− MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy,
957− implicit, style, mark, mark);
958−
959− return 1;
960−
961−error:
962− yaml_free(anchor_copy);
963− yaml_free(tag_copy);
964−
965− return 0;
966−}
967−
968−/*
969− * Create MAPPING-END.
970− */
971−
972−YAML_DECLARE(int)
973−yaml_mapping_end_event_initialize(yaml_event_t *event)
974−{
975− yaml_mark_t mark = { 0, 0, 0 };
976−
977− assert(event); /* Non-NULL event object is expected. */
978−
979− MAPPING_END_EVENT_INIT(*event, mark, mark);
980−
981− return 1;
982−}
983−
984−/*
985− * Destroy an event object.
986− */
987−
988−YAML_DECLARE(void)
989−yaml_event_delete(yaml_event_t *event)
990−{
991− yaml_tag_directive_t *tag_directive;
992−
993− assert(event); /* Non-NULL event object expected. */
994−
995− switch (event->type)
996− {
997− case YAML_DOCUMENT_START_EVENT:
998− yaml_free(event->data.document_start.version_directive);
999− for (tag_directive = event->data.document_start.tag_directives.start;
1000− tag_directive != event->data.document_start.tag_directives.end;
1001− tag_directive++) {
1002− yaml_free(tag_directive->handle);
1003− yaml_free(tag_directive->prefix);
1004− }
1005− yaml_free(event->data.document_start.tag_directives.start);
1006− break;
1007−
1008− case YAML_ALIAS_EVENT:
1009− yaml_free(event->data.alias.anchor);
1010− break;
1011−
1012− case YAML_SCALAR_EVENT:
1013− yaml_free(event->data.scalar.anchor);
1014− yaml_free(event->data.scalar.tag);
1015− yaml_free(event->data.scalar.value);
1016− break;
1017−
1018− case YAML_SEQUENCE_START_EVENT:
1019− yaml_free(event->data.sequence_start.anchor);
1020− yaml_free(event->data.sequence_start.tag);
1021− break;
1022−
1023− case YAML_MAPPING_START_EVENT:
1024− yaml_free(event->data.mapping_start.anchor);
1025− yaml_free(event->data.mapping_start.tag);
1026− break;
1027−
1028− default:
1029− break;
1030− }
1031−
1032− memset(event, 0, sizeof(yaml_event_t));
1033−}
1034−
1035−/*
1036− * Create a document object.
1037− */
1038−
1039−YAML_DECLARE(int)
1040−yaml_document_initialize(yaml_document_t *document,
1041− yaml_version_directive_t *version_directive,
1042− yaml_tag_directive_t *tag_directives_start,
1043− yaml_tag_directive_t *tag_directives_end,
1044− int start_implicit, int end_implicit)
1045−{
1046− struct {
1047− yaml_error_type_t error;
1048− } context;
1049− struct {
1050− yaml_node_t *start;
1051− yaml_node_t *end;
1052− yaml_node_t *top;
1053− } nodes = { NULL, NULL, NULL };
1054− yaml_version_directive_t *version_directive_copy = NULL;
1055− struct {
1056− yaml_tag_directive_t *start;
1057− yaml_tag_directive_t *end;
1058− yaml_tag_directive_t *top;
1059− } tag_directives_copy = { NULL, NULL, NULL };
1060− yaml_tag_directive_t value = { NULL, NULL };
1061− yaml_mark_t mark = { 0, 0, 0 };
1062−
1063− assert(document); /* Non-NULL document object is expected. */
1064− assert((tag_directives_start && tag_directives_end) ||
1065− (tag_directives_start == tag_directives_end));
1066− /* Valid tag directives are expected. */
1067−
1068− if (!STACK_INIT(&context, nodes, yaml_node_t*)) goto error;
1069−
1070− if (version_directive) {
1071− version_directive_copy = YAML_MALLOC_STATIC(yaml_version_directive_t);
1072− if (!version_directive_copy) goto error;
1073− version_directive_copy->major = version_directive->major;
1074− version_directive_copy->minor = version_directive->minor;
1075− }
1076−
1077− if (tag_directives_start != tag_directives_end) {
1078− yaml_tag_directive_t *tag_directive;
1079− if (!STACK_INIT(&context, tag_directives_copy, yaml_tag_directive_t*))
1080− goto error;
1081− for (tag_directive = tag_directives_start;
1082− tag_directive != tag_directives_end; tag_directive ++) {
1083− assert(tag_directive->handle);
1084− assert(tag_directive->prefix);
1085− if (!yaml_check_utf8(tag_directive->handle,
1086− strlen((char *)tag_directive->handle)))
1087− goto error;
1088− if (!yaml_check_utf8(tag_directive->prefix,
1089− strlen((char *)tag_directive->prefix)))
1090− goto error;
1091− value.handle = yaml_strdup(tag_directive->handle);
1092− value.prefix = yaml_strdup(tag_directive->prefix);
1093− if (!value.handle || !value.prefix) goto error;
1094− if (!PUSH(&context, tag_directives_copy, value))
1095− goto error;
1096− value.handle = NULL;
1097− value.prefix = NULL;
1098− }
1099− }
1100−
1101− DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,
1102− tag_directives_copy.start, tag_directives_copy.top,
1103− start_implicit, end_implicit, mark, mark);
1104−
1105− return 1;
1106−
1107−error:
1108− STACK_DEL(&context, nodes);
1109− yaml_free(version_directive_copy);
1110− while (!STACK_EMPTY(&context, tag_directives_copy)) {
1111− yaml_tag_directive_t value = POP(&context, tag_directives_copy);
1112− yaml_free(value.handle);
1113− yaml_free(value.prefix);
1114− }
1115− STACK_DEL(&context, tag_directives_copy);
1116− yaml_free(value.handle);
1117− yaml_free(value.prefix);
1118−
1119− return 0;
1120−}
1121−
1122−/*
1123− * Destroy a document object.
1124− */
1125−
1126−YAML_DECLARE(void)
1127−yaml_document_delete(yaml_document_t *document)
1128−{
1129− struct {
1130− yaml_error_type_t error;
1131− } context;
1132− yaml_tag_directive_t *tag_directive;
1133−
1134− context.error = YAML_NO_ERROR; /* Eliminate a compliler warning. */
1135−
1136− assert(document); /* Non-NULL document object is expected. */
1137−
1138− while (!STACK_EMPTY(&context, document->nodes)) {
1139− yaml_node_t node = POP(&context, document->nodes);
1140− yaml_free(node.tag);
1141− switch (node.type) {
1142− case YAML_SCALAR_NODE:
1143− yaml_free(node.data.scalar.value);
1144− break;
1145− case YAML_SEQUENCE_NODE:
1146− STACK_DEL(&context, node.data.sequence.items);
1147− break;
1148− case YAML_MAPPING_NODE:
1149− STACK_DEL(&context, node.data.mapping.pairs);
1150− break;
1151− default:
1152− assert(0); /* Should not happen. */
1153− }
1154− }
1155− STACK_DEL(&context, document->nodes);
1156−
1157− yaml_free(document->version_directive);
1158− for (tag_directive = document->tag_directives.start;
1159− tag_directive != document->tag_directives.end;
1160− tag_directive++) {
1161− yaml_free(tag_directive->handle);
1162− yaml_free(tag_directive->prefix);
1163− }
1164− yaml_free(document->tag_directives.start);
1165−
1166− memset(document, 0, sizeof(yaml_document_t));
1167−}
1168−
1169−/**
1170− * Get a document node.
1171− */
1172−
1173−YAML_DECLARE(yaml_node_t *)
1174−yaml_document_get_node(yaml_document_t *document, int index)
1175−{
1176− assert(document); /* Non-NULL document object is expected. */
1177−
1178− if (index > 0 && document->nodes.start + index <= document->nodes.top) {
1179− return document->nodes.start + index - 1;
1180− }
1181− return NULL;
1182−}
1183−
1184−/**
1185− * Get the root object.
1186− */
1187−
1188−YAML_DECLARE(yaml_node_t *)
1189−yaml_document_get_root_node(yaml_document_t *document)
1190−{
1191− assert(document); /* Non-NULL document object is expected. */
1192−
1193− if (document->nodes.top != document->nodes.start) {
1194− return document->nodes.start;
1195− }
1196− return NULL;
1197−}
1198−
1199−/*
1200− * Add a scalar node to a document.
1201− */
1202−
1203−YAML_DECLARE(int)
1204−yaml_document_add_scalar(yaml_document_t *document,
1205− yaml_char_t *tag, yaml_char_t *value, int length,
1206− yaml_scalar_style_t style)
1207−{
1208− struct {
1209− yaml_error_type_t error;
1210− } context;
1211− yaml_mark_t mark = { 0, 0, 0 };
1212− yaml_char_t *tag_copy = NULL;
1213− yaml_char_t *value_copy = NULL;
1214− yaml_node_t node;
1215−
1216− assert(document); /* Non-NULL document object is expected. */
1217− assert(value); /* Non-NULL value is expected. */
1218−
1219− if (!tag) {
1220− tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG;
1221− }
1222−
1223− if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1224− tag_copy = yaml_strdup(tag);
1225− if (!tag_copy) goto error;
1226−
1227− if (length < 0) {
1228− length = strlen((char *)value);
1229− }
1230−
1231− if (!yaml_check_utf8(value, length)) goto error;
1232− value_copy = YAML_MALLOC(length+1);
1233− if (!value_copy) goto error;
1234− memcpy(value_copy, value, length);
1235− value_copy[length] = '\0';
1236−
1237− SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark);
1238− if (!PUSH(&context, document->nodes, node)) goto error;
1239−
1240− return document->nodes.top - document->nodes.start;
1241−
1242−error:
1243− yaml_free(tag_copy);
1244− yaml_free(value_copy);
1245−
1246− return 0;
1247−}
1248−
1249−/*
1250− * Add a sequence node to a document.
1251− */
1252−
1253−YAML_DECLARE(int)
1254−yaml_document_add_sequence(yaml_document_t *document,
1255− yaml_char_t *tag, yaml_sequence_style_t style)
1256−{
1257− struct {
1258− yaml_error_type_t error;
1259− } context;
1260− yaml_mark_t mark = { 0, 0, 0 };
1261− yaml_char_t *tag_copy = NULL;
1262− struct {
1263− yaml_node_item_t *start;
1264− yaml_node_item_t *end;
1265− yaml_node_item_t *top;
1266− } items = { NULL, NULL, NULL };
1267− yaml_node_t node;
1268−
1269− assert(document); /* Non-NULL document object is expected. */
1270−
1271− if (!tag) {
1272− tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG;
1273− }
1274−
1275− if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1276− tag_copy = yaml_strdup(tag);
1277− if (!tag_copy) goto error;
1278−
1279− if (!STACK_INIT(&context, items, yaml_node_item_t*)) goto error;
1280−
1281− SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,
1282− style, mark, mark);
1283− if (!PUSH(&context, document->nodes, node)) goto error;
1284−
1285− return document->nodes.top - document->nodes.start;
1286−
1287−error:
1288− STACK_DEL(&context, items);
1289− yaml_free(tag_copy);
1290−
1291− return 0;
1292−}
1293−
1294−/*
1295− * Add a mapping node to a document.
1296− */
1297−
1298−YAML_DECLARE(int)
1299−yaml_document_add_mapping(yaml_document_t *document,
1300− yaml_char_t *tag, yaml_mapping_style_t style)
1301−{
1302− struct {
1303− yaml_error_type_t error;
1304− } context;
1305− yaml_mark_t mark = { 0, 0, 0 };
1306− yaml_char_t *tag_copy = NULL;
1307− struct {
1308− yaml_node_pair_t *start;
1309− yaml_node_pair_t *end;
1310− yaml_node_pair_t *top;
1311− } pairs = { NULL, NULL, NULL };
1312− yaml_node_t node;
1313−
1314− assert(document); /* Non-NULL document object is expected. */
1315−
1316− if (!tag) {
1317− tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG;
1318− }
1319−
1320− if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error;
1321− tag_copy = yaml_strdup(tag);
1322− if (!tag_copy) goto error;
1323−
1324− if (!STACK_INIT(&context, pairs, yaml_node_pair_t*)) goto error;
1325−
1326− MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,
1327− style, mark, mark);
1328− if (!PUSH(&context, document->nodes, node)) goto error;
1329−
1330− return document->nodes.top - document->nodes.start;
1331−
1332−error:
1333− STACK_DEL(&context, pairs);
1334− yaml_free(tag_copy);
1335−
1336− return 0;
1337−}
1338−
1339−/*
1340− * Append an item to a sequence node.
1341− */
1342−
1343−YAML_DECLARE(int)
1344−yaml_document_append_sequence_item(yaml_document_t *document,
1345− int sequence, int item)
1346−{
1347− struct {
1348− yaml_error_type_t error;
1349− } context;
1350−
1351− assert(document); /* Non-NULL document is required. */
1352− assert(sequence > 0
1353− && document->nodes.start + sequence <= document->nodes.top);
1354− /* Valid sequence id is required. */
1355− assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE);
1356− /* A sequence node is required. */
1357− assert(item > 0 && document->nodes.start + item <= document->nodes.top);
1358− /* Valid item id is required. */
1359−
1360− if (!PUSH(&context,
1361− document->nodes.start[sequence-1].data.sequence.items, item))
1362− return 0;
1363−
1364− return 1;
1365−}
1366−
1367−/*
1368− * Append a pair of a key and a value to a mapping node.
1369− */
1370−
1371−YAML_DECLARE(int)
1372−yaml_document_append_mapping_pair(yaml_document_t *document,
1373− int mapping, int key, int value)
1374−{
1375− struct {
1376− yaml_error_type_t error;
1377− } context;
1378−
1379− yaml_node_pair_t pair;
1380−
1381− assert(document); /* Non-NULL document is required. */
1382− assert(mapping > 0
1383− && document->nodes.start + mapping <= document->nodes.top);
1384− /* Valid mapping id is required. */
1385− assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE);
1386− /* A mapping node is required. */
1387− assert(key > 0 && document->nodes.start + key <= document->nodes.top);
1388− /* Valid key id is required. */
1389− assert(value > 0 && document->nodes.start + value <= document->nodes.top);
1390− /* Valid value id is required. */
1391−
1392− pair.key = key;
1393− pair.value = value;
1394−
1395− if (!PUSH(&context,
1396− document->nodes.start[mapping-1].data.mapping.pairs, pair))
1397− return 0;
1398−
1399− return 1;
1400−}
1401−
1402−
c/helper.c → libyaml/c/helper.crenamed

The content is the same.

libyaml/dumper.cdeleted−394
@@ -1,394 +0,0 @@
1−
2−#include "yaml_private.h"
3−
4−/*
5− * API functions.
6− */
7−
8−YAML_DECLARE(int)
9−yaml_emitter_open(yaml_emitter_t *emitter);
10−
11−YAML_DECLARE(int)
12−yaml_emitter_close(yaml_emitter_t *emitter);
13−
14−YAML_DECLARE(int)
15−yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
16−
17−/*
18− * Clean up functions.
19− */
20−
21−static void
22−yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter);
23−
24−/*
25− * Anchor functions.
26− */
27−
28−static void
29−yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index);
30−
31−static yaml_char_t *
32−yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id);
33−
34−
35−/*
36− * Serialize functions.
37− */
38−
39−static int
40−yaml_emitter_dump_node(yaml_emitter_t *emitter, int index);
41−
42−static int
43−yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor);
44−
45−static int
46−yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
47− yaml_char_t *anchor);
48−
49−static int
50−yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
51− yaml_char_t *anchor);
52−
53−static int
54−yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
55− yaml_char_t *anchor);
56−
57−/*
58− * Issue a STREAM-START event.
59− */
60−
61−YAML_DECLARE(int)
62−yaml_emitter_open(yaml_emitter_t *emitter)
63−{
64− yaml_event_t event;
65− yaml_mark_t mark = { 0, 0, 0 };
66−
67− assert(emitter); /* Non-NULL emitter object is required. */
68− assert(!emitter->opened); /* Emitter should not be opened yet. */
69−
70− STREAM_START_EVENT_INIT(event, YAML_ANY_ENCODING, mark, mark);
71−
72− if (!yaml_emitter_emit(emitter, &event)) {
73− return 0;
74− }
75−
76− emitter->opened = 1;
77−
78− return 1;
79−}
80−
81−/*
82− * Issue a STREAM-END event.
83− */
84−
85−YAML_DECLARE(int)
86−yaml_emitter_close(yaml_emitter_t *emitter)
87−{
88− yaml_event_t event;
89− yaml_mark_t mark = { 0, 0, 0 };
90−
91− assert(emitter); /* Non-NULL emitter object is required. */
92− assert(emitter->opened); /* Emitter should be opened. */
93−
94− if (emitter->closed) return 1;
95−
96− STREAM_END_EVENT_INIT(event, mark, mark);
97−
98− if (!yaml_emitter_emit(emitter, &event)) {
99− return 0;
100− }
101−
102− emitter->closed = 1;
103−
104− return 1;
105−}
106−
107−/*
108− * Dump a YAML document.
109− */
110−
111−YAML_DECLARE(int)
112−yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document)
113−{
114− yaml_event_t event;
115− yaml_mark_t mark = { 0, 0, 0 };
116−
117− assert(emitter); /* Non-NULL emitter object is required. */
118− assert(document); /* Non-NULL emitter object is expected. */
119−
120− emitter->document = document;
121−
122− if (!emitter->opened) {
123− if (!yaml_emitter_open(emitter)) goto error;
124− }
125−
126− if (STACK_EMPTY(emitter, document->nodes)) {
127− if (!yaml_emitter_close(emitter)) goto error;
128− yaml_emitter_delete_document_and_anchors(emitter);
129− return 1;
130− }
131−
132− assert(emitter->opened); /* Emitter should be opened. */
133−
134− emitter->anchors = yaml_malloc(sizeof(*(emitter->anchors))
135− * (document->nodes.top - document->nodes.start));
136− if (!emitter->anchors) goto error;
137− memset(emitter->anchors, 0, sizeof(*(emitter->anchors))
138− * (document->nodes.top - document->nodes.start));
139−
140− DOCUMENT_START_EVENT_INIT(event, document->version_directive,
141− document->tag_directives.start, document->tag_directives.end,
142− document->start_implicit, mark, mark);
143− if (!yaml_emitter_emit(emitter, &event)) goto error;
144−
145− yaml_emitter_anchor_node(emitter, 1);
146− if (!yaml_emitter_dump_node(emitter, 1)) goto error;
147−
148− DOCUMENT_END_EVENT_INIT(event, document->end_implicit, mark, mark);
149− if (!yaml_emitter_emit(emitter, &event)) goto error;
150−
151− yaml_emitter_delete_document_and_anchors(emitter);
152−
153− return 1;
154−
155−error:
156−
157− yaml_emitter_delete_document_and_anchors(emitter);
158−
159− return 0;
160−}
161−
162−/*
163− * Clean up the emitter object after a document is dumped.
164− */
165−
166−static void
167−yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter)
168−{
169− int index;
170−
171− if (!emitter->anchors) {
172− yaml_document_delete(emitter->document);
173− emitter->document = NULL;
174− return;
175− }
176−
177− for (index = 0; emitter->document->nodes.start + index
178− < emitter->document->nodes.top; index ++) {
179− yaml_node_t node = emitter->document->nodes.start[index];
180− if (!emitter->anchors[index].serialized) {
181− yaml_free(node.tag);
182− if (node.type == YAML_SCALAR_NODE) {
183− yaml_free(node.data.scalar.value);
184− }
185− }
186− if (node.type == YAML_SEQUENCE_NODE) {
187− STACK_DEL(emitter, node.data.sequence.items);
188− }
189− if (node.type == YAML_MAPPING_NODE) {
190− STACK_DEL(emitter, node.data.mapping.pairs);
191− }
192− }
193−
194− STACK_DEL(emitter, emitter->document->nodes);
195− yaml_free(emitter->anchors);
196−
197− emitter->anchors = NULL;
198− emitter->last_anchor_id = 0;
199− emitter->document = NULL;
200−}
201−
202−/*
203− * Check the references of a node and assign the anchor id if needed.
204− */
205−
206−static void
207−yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index)
208−{
209− yaml_node_t *node = emitter->document->nodes.start + index - 1;
210− yaml_node_item_t *item;
211− yaml_node_pair_t *pair;
212−
213− emitter->anchors[index-1].references ++;
214−
215− if (emitter->anchors[index-1].references == 1) {
216− switch (node->type) {
217− case YAML_SEQUENCE_NODE:
218− for (item = node->data.sequence.items.start;
219− item < node->data.sequence.items.top; item ++) {
220− yaml_emitter_anchor_node(emitter, *item);
221− }
222− break;
223− case YAML_MAPPING_NODE:
224− for (pair = node->data.mapping.pairs.start;
225− pair < node->data.mapping.pairs.top; pair ++) {
226− yaml_emitter_anchor_node(emitter, pair->key);
227− yaml_emitter_anchor_node(emitter, pair->value);
228− }
229− break;
230− default:
231− break;
232− }
233− }
234−
235− else if (emitter->anchors[index-1].references == 2) {
236− emitter->anchors[index-1].anchor = (++ emitter->last_anchor_id);
237− }
238−}
239−
240−/*
241− * Generate a textual representation for an anchor.
242− */
243−
244−#define ANCHOR_TEMPLATE "id%03d"
245−#define ANCHOR_TEMPLATE_LENGTH 16
246−
247−static yaml_char_t *
248−yaml_emitter_generate_anchor(SHIM(yaml_emitter_t *emitter), int anchor_id)
249−{
250− yaml_char_t *anchor = YAML_MALLOC(ANCHOR_TEMPLATE_LENGTH);
251−
252− if (!anchor) return NULL;
253−
254− sprintf((char *)anchor, ANCHOR_TEMPLATE, anchor_id);
255−
256− return anchor;
257−}
258−
259−/*
260− * Serialize a node.
261− */
262−
263−static int
264−yaml_emitter_dump_node(yaml_emitter_t *emitter, int index)
265−{
266− yaml_node_t *node = emitter->document->nodes.start + index - 1;
267− int anchor_id = emitter->anchors[index-1].anchor;
268− yaml_char_t *anchor = NULL;
269−
270− if (anchor_id) {
271− anchor = yaml_emitter_generate_anchor(emitter, anchor_id);
272− if (!anchor) return 0;
273− }
274−
275− if (emitter->anchors[index-1].serialized) {
276− return yaml_emitter_dump_alias(emitter, anchor);
277− }
278−
279− emitter->anchors[index-1].serialized = 1;
280−
281− switch (node->type) {
282− case YAML_SCALAR_NODE:
283− return yaml_emitter_dump_scalar(emitter, node, anchor);
284− case YAML_SEQUENCE_NODE:
285− return yaml_emitter_dump_sequence(emitter, node, anchor);
286− case YAML_MAPPING_NODE:
287− return yaml_emitter_dump_mapping(emitter, node, anchor);
288− default:
289− assert(0); /* Could not happen. */
290− break;
291− }
292−
293− return 0; /* Could not happen. */
294−}
295−
296−/*
297− * Serialize an alias.
298− */
299−
300−static int
301−yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor)
302−{
303− yaml_event_t event;
304− yaml_mark_t mark = { 0, 0, 0 };
305−
306− ALIAS_EVENT_INIT(event, anchor, mark, mark);
307−
308− return yaml_emitter_emit(emitter, &event);
309−}
310−
311−/*
312− * Serialize a scalar.
313− */
314−
315−static int
316−yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
317− yaml_char_t *anchor)
318−{
319− yaml_event_t event;
320− yaml_mark_t mark = { 0, 0, 0 };
321−
322− int plain_implicit = (strcmp((char *)node->tag,
323− YAML_DEFAULT_SCALAR_TAG) == 0);
324− int quoted_implicit = (strcmp((char *)node->tag,
325− YAML_DEFAULT_SCALAR_TAG) == 0);
326−
327− SCALAR_EVENT_INIT(event, anchor, node->tag, node->data.scalar.value,
328− node->data.scalar.length, plain_implicit, quoted_implicit,
329− node->data.scalar.style, mark, mark);
330−
331− return yaml_emitter_emit(emitter, &event);
332−}
333−
334−/*
335− * Serialize a sequence.
336− */
337−
338−static int
339−yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
340− yaml_char_t *anchor)
341−{
342− yaml_event_t event;
343− yaml_mark_t mark = { 0, 0, 0 };
344−
345− int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_SEQUENCE_TAG) == 0);
346−
347− yaml_node_item_t *item;
348−
349− SEQUENCE_START_EVENT_INIT(event, anchor, node->tag, implicit,
350− node->data.sequence.style, mark, mark);
351− if (!yaml_emitter_emit(emitter, &event)) return 0;
352−
353− for (item = node->data.sequence.items.start;
354− item < node->data.sequence.items.top; item ++) {
355− if (!yaml_emitter_dump_node(emitter, *item)) return 0;
356− }
357−
358− SEQUENCE_END_EVENT_INIT(event, mark, mark);
359− if (!yaml_emitter_emit(emitter, &event)) return 0;
360−
361− return 1;
362−}
363−
364−/*
365− * Serialize a mapping.
366− */
367−
368−static int
369−yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
370− yaml_char_t *anchor)
371−{
372− yaml_event_t event;
373− yaml_mark_t mark = { 0, 0, 0 };
374−
375− int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_MAPPING_TAG) == 0);
376−
377− yaml_node_pair_t *pair;
378−
379− MAPPING_START_EVENT_INIT(event, anchor, node->tag, implicit,
380− node->data.mapping.style, mark, mark);
381− if (!yaml_emitter_emit(emitter, &event)) return 0;
382−
383− for (pair = node->data.mapping.pairs.start;
384− pair < node->data.mapping.pairs.top; pair ++) {
385− if (!yaml_emitter_dump_node(emitter, pair->key)) return 0;
386− if (!yaml_emitter_dump_node(emitter, pair->value)) return 0;
387− }
388−
389− MAPPING_END_EVENT_INIT(event, mark, mark);
390− if (!yaml_emitter_emit(emitter, &event)) return 0;
391−
392− return 1;
393−}
394−
libyaml/emitter.cdeleted−2324
@@ -1,2324 +0,0 @@
1−
2−#include "yaml_private.h"
3−
4−/*
5− * Flush the buffer if needed.
6− */
7−
8−#define FLUSH(emitter) \
9− ((emitter->buffer.pointer+5 < emitter->buffer.end) \
10− || yaml_emitter_flush(emitter))
11−
12−/*
13− * Put a character to the output buffer.
14− */
15−
16−#define PUT(emitter,value) \
17− (FLUSH(emitter) \
18− && (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \
19− emitter->column ++, \
20− 1))
21−
22−/*
23− * Put a line break to the output buffer.
24− */
25−
26−#define PUT_BREAK(emitter) \
27− (FLUSH(emitter) \
28− && ((emitter->line_break == YAML_CR_BREAK ? \
29− (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \
30− emitter->line_break == YAML_LN_BREAK ? \
31− (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \
32− emitter->line_break == YAML_CRLN_BREAK ? \
33− (*(emitter->buffer.pointer++) = (yaml_char_t) '\r', \
34− *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \
35− emitter->column = 0, \
36− emitter->line ++, \
37− 1))
38−
39−/*
40− * Copy a character from a string into buffer.
41− */
42−
43−#define WRITE(emitter,string) \
44− (FLUSH(emitter) \
45− && (COPY(emitter->buffer,string), \
46− emitter->column ++, \
47− 1))
48−
49−/*
50− * Copy a line break character from a string into buffer.
51− */
52−
53−#define WRITE_BREAK(emitter,string) \
54− (FLUSH(emitter) \
55− && (CHECK(string,'\n') ? \
56− (PUT_BREAK(emitter), \
57− string.pointer ++, \
58− 1) : \
59− (COPY(emitter->buffer,string), \
60− emitter->column = 0, \
61− emitter->line ++, \
62− 1)))
63−
64−/*
65− * API functions.
66− */
67−
68−YAML_DECLARE(int)
69−yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
70−
71−/*
72− * Utility functions.
73− */
74−
75−static int
76−yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem);
77−
78−static int
79−yaml_emitter_need_more_events(yaml_emitter_t *emitter);
80−
81−static int
82−yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
83− yaml_tag_directive_t value, int allow_duplicates);
84−
85−static int
86−yaml_emitter_increase_indent(yaml_emitter_t *emitter,
87− int flow, int indentless);
88−
89−/*
90− * State functions.
91− */
92−
93−static int
94−yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event);
95−
96−static int
97−yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
98− yaml_event_t *event);
99−
100−static int
101−yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
102− yaml_event_t *event, int first);
103−
104−static int
105−yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
106− yaml_event_t *event);
107−
108−static int
109−yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
110− yaml_event_t *event);
111−
112−static int
113−yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
114− yaml_event_t *event, int first);
115−
116−static int
117−yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
118− yaml_event_t *event, int first);
119−
120−static int
121−yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
122− yaml_event_t *event, int simple);
123−
124−static int
125−yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
126− yaml_event_t *event, int first);
127−
128−static int
129−yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
130− yaml_event_t *event, int first);
131−
132−static int
133−yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
134− yaml_event_t *event, int simple);
135−
136−static int
137−yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
138− int root, int sequence, int mapping, int simple_key);
139−
140−static int
141−yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event);
142−
143−static int
144−yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event);
145−
146−static int
147−yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event);
148−
149−static int
150−yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event);
151−
152−/*
153− * Checkers.
154− */
155−
156−static int
157−yaml_emitter_check_empty_document(yaml_emitter_t *emitter);
158−
159−static int
160−yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter);
161−
162−static int
163−yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter);
164−
165−static int
166−yaml_emitter_check_simple_key(yaml_emitter_t *emitter);
167−
168−static int
169−yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event);
170−
171−/*
172− * Processors.
173− */
174−
175−static int
176−yaml_emitter_process_anchor(yaml_emitter_t *emitter);
177−
178−static int
179−yaml_emitter_process_tag(yaml_emitter_t *emitter);
180−
181−static int
182−yaml_emitter_process_scalar(yaml_emitter_t *emitter);
183−
184−/*
185− * Analyzers.
186− */
187−
188−static int
189−yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
190− yaml_version_directive_t version_directive);
191−
192−static int
193−yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
194− yaml_tag_directive_t tag_directive);
195−
196−static int
197−yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
198− yaml_char_t *anchor, int alias);
199−
200−static int
201−yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
202− yaml_char_t *tag);
203−
204−static int
205−yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
206− yaml_char_t *value, size_t length);
207−
208−static int
209−yaml_emitter_analyze_event(yaml_emitter_t *emitter,
210− yaml_event_t *event);
211−
212−/*
213− * Writers.
214− */
215−
216−static int
217−yaml_emitter_write_bom(yaml_emitter_t *emitter);
218−
219−static int
220−yaml_emitter_write_indent(yaml_emitter_t *emitter);
221−
222−static int
223−yaml_emitter_write_indicator(yaml_emitter_t *emitter,
224− char *indicator, int need_whitespace,
225− int is_whitespace, int is_indention);
226−
227−static int
228−yaml_emitter_write_anchor(yaml_emitter_t *emitter,
229− yaml_char_t *value, size_t length);
230−
231−static int
232−yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
233− yaml_char_t *value, size_t length);
234−
235−static int
236−yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
237− yaml_char_t *value, size_t length, int need_whitespace);
238−
239−static int
240−yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
241− yaml_char_t *value, size_t length, int allow_breaks);
242−
243−static int
244−yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
245− yaml_char_t *value, size_t length, int allow_breaks);
246−
247−static int
248−yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
249− yaml_char_t *value, size_t length, int allow_breaks);
250−
251−static int
252−yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
253− yaml_string_t string);
254−
255−static int
256−yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
257− yaml_char_t *value, size_t length);
258−
259−static int
260−yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
261− yaml_char_t *value, size_t length);
262−
263−/*
264− * Set an emitter error and return 0.
265− */
266−
267−static int
268−yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem)
269−{
270− emitter->error = YAML_EMITTER_ERROR;
271− emitter->problem = problem;
272−
273− return 0;
274−}
275−
276−/*
277− * Emit an event.
278− */
279−
280−YAML_DECLARE(int)
281−yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event)
282−{
283− if (!ENQUEUE(emitter, emitter->events, *event)) {
284− yaml_event_delete(event);
285− return 0;
286− }
287−
288− while (!yaml_emitter_need_more_events(emitter)) {
289− if (!yaml_emitter_analyze_event(emitter, emitter->events.head))
290− return 0;
291− if (!yaml_emitter_state_machine(emitter, emitter->events.head))
292− return 0;
293− yaml_event_delete(&DEQUEUE(emitter, emitter->events));
294− }
295−
296− return 1;
297−}
298−
299−/*
300− * Check if we need to accumulate more events before emitting.
301− *
302− * We accumulate extra
303− * - 1 event for DOCUMENT-START
304− * - 2 events for SEQUENCE-START
305− * - 3 events for MAPPING-START
306− */
307−
308−static int
309−yaml_emitter_need_more_events(yaml_emitter_t *emitter)
310−{
311− int level = 0;
312− int accumulate = 0;
313− yaml_event_t *event;
314−
315− if (QUEUE_EMPTY(emitter, emitter->events))
316− return 1;
317−
318− switch (emitter->events.head->type) {
319− case YAML_DOCUMENT_START_EVENT:
320− accumulate = 1;
321− break;
322− case YAML_SEQUENCE_START_EVENT:
323− accumulate = 2;
324− break;
325− case YAML_MAPPING_START_EVENT:
326− accumulate = 3;
327− break;
328− default:
329− return 0;
330− }
331−
332− if (emitter->events.tail - emitter->events.head > accumulate)
333− return 0;
334−
335− for (event = emitter->events.head; event != emitter->events.tail; event ++) {
336− switch (event->type) {
337− case YAML_STREAM_START_EVENT:
338− case YAML_DOCUMENT_START_EVENT:
339− case YAML_SEQUENCE_START_EVENT:
340− case YAML_MAPPING_START_EVENT:
341− level += 1;
342− break;
343− case YAML_STREAM_END_EVENT:
344− case YAML_DOCUMENT_END_EVENT:
345− case YAML_SEQUENCE_END_EVENT:
346− case YAML_MAPPING_END_EVENT:
347− level -= 1;
348− break;
349− default:
350− break;
351− }
352− if (!level)
353− return 0;
354− }
355−
356− return 1;
357−}
358−
359−/*
360− * Append a directive to the directives stack.
361− */
362−
363−static int
364−yaml_emitter_append_tag_directive(yaml_emitter_t *emitter,
365− yaml_tag_directive_t value, int allow_duplicates)
366−{
367− yaml_tag_directive_t *tag_directive;
368− yaml_tag_directive_t copy = { NULL, NULL };
369−
370− for (tag_directive = emitter->tag_directives.start;
371− tag_directive != emitter->tag_directives.top; tag_directive ++) {
372− if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
373− if (allow_duplicates)
374− return 1;
375− return yaml_emitter_set_emitter_error(emitter,
376− "duplicate %TAG directive");
377− }
378− }
379−
380− copy.handle = yaml_strdup(value.handle);
381− copy.prefix = yaml_strdup(value.prefix);
382− if (!copy.handle || !copy.prefix) {
383− emitter->error = YAML_MEMORY_ERROR;
384− goto error;
385− }
386−
387− if (!PUSH(emitter, emitter->tag_directives, copy))
388− goto error;
389−
390− return 1;
391−
392−error:
393− yaml_free(copy.handle);
394− yaml_free(copy.prefix);
395− return 0;
396−}
397−
398−/*
399− * Increase the indentation level.
400− */
401−
402−static int
403−yaml_emitter_increase_indent(yaml_emitter_t *emitter,
404− int flow, int indentless)
405−{
406− if (!PUSH(emitter, emitter->indents, emitter->indent))
407− return 0;
408−
409− if (emitter->indent < 0) {
410− emitter->indent = flow ? emitter->best_indent : 0;
411− }
412− else if (!indentless) {
413− emitter->indent += emitter->best_indent;
414− }
415−
416− return 1;
417−}
418−
419−/*
420− * State dispatcher.
421− */
422−
423−static int
424−yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event)
425−{
426− switch (emitter->state)
427− {
428− case YAML_EMIT_STREAM_START_STATE:
429− return yaml_emitter_emit_stream_start(emitter, event);
430−
431− case YAML_EMIT_FIRST_DOCUMENT_START_STATE:
432− return yaml_emitter_emit_document_start(emitter, event, 1);
433−
434− case YAML_EMIT_DOCUMENT_START_STATE:
435− return yaml_emitter_emit_document_start(emitter, event, 0);
436−
437− case YAML_EMIT_DOCUMENT_CONTENT_STATE:
438− return yaml_emitter_emit_document_content(emitter, event);
439−
440− case YAML_EMIT_DOCUMENT_END_STATE:
441− return yaml_emitter_emit_document_end(emitter, event);
442−
443− case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:
444− return yaml_emitter_emit_flow_sequence_item(emitter, event, 1);
445−
446− case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE:
447− return yaml_emitter_emit_flow_sequence_item(emitter, event, 0);
448−
449− case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:
450− return yaml_emitter_emit_flow_mapping_key(emitter, event, 1);
451−
452− case YAML_EMIT_FLOW_MAPPING_KEY_STATE:
453− return yaml_emitter_emit_flow_mapping_key(emitter, event, 0);
454−
455− case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:
456− return yaml_emitter_emit_flow_mapping_value(emitter, event, 1);
457−
458− case YAML_EMIT_FLOW_MAPPING_VALUE_STATE:
459− return yaml_emitter_emit_flow_mapping_value(emitter, event, 0);
460−
461− case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:
462− return yaml_emitter_emit_block_sequence_item(emitter, event, 1);
463−
464− case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE:
465− return yaml_emitter_emit_block_sequence_item(emitter, event, 0);
466−
467− case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:
468− return yaml_emitter_emit_block_mapping_key(emitter, event, 1);
469−
470− case YAML_EMIT_BLOCK_MAPPING_KEY_STATE:
471− return yaml_emitter_emit_block_mapping_key(emitter, event, 0);
472−
473− case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:
474− return yaml_emitter_emit_block_mapping_value(emitter, event, 1);
475−
476− case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE:
477− return yaml_emitter_emit_block_mapping_value(emitter, event, 0);
478−
479− case YAML_EMIT_END_STATE:
480− return yaml_emitter_set_emitter_error(emitter,
481− "expected nothing after STREAM-END");
482−
483− default:
484− assert(1); /* Invalid state. */
485− }
486−
487− return 0;
488−}
489−
490−/*
491− * Expect STREAM-START.
492− */
493−
494−static int
495−yaml_emitter_emit_stream_start(yaml_emitter_t *emitter,
496− yaml_event_t *event)
497−{
498− if (event->type == YAML_STREAM_START_EVENT)
499− {
500− if (!emitter->encoding) {
501− emitter->encoding = event->data.stream_start.encoding;
502− }
503−
504− if (!emitter->encoding) {
505− emitter->encoding = YAML_UTF8_ENCODING;
506− }
507−
508− if (emitter->best_indent < 2 || emitter->best_indent > 9) {
509− emitter->best_indent = 2;
510− }
511−
512− if (emitter->best_width >= 0
513− && emitter->best_width <= emitter->best_indent*2) {
514− emitter->best_width = 80;
515− }
516−
517− if (emitter->best_width < 0) {
518− emitter->best_width = INT_MAX;
519− }
520−
521− if (!emitter->line_break) {
522− emitter->line_break = YAML_LN_BREAK;
523− }
524−
525− emitter->indent = -1;
526−
527− emitter->line = 0;
528− emitter->column = 0;
529− emitter->whitespace = 1;
530− emitter->indention = 1;
531−
532− if (emitter->encoding != YAML_UTF8_ENCODING) {
533− if (!yaml_emitter_write_bom(emitter))
534− return 0;
535− }
536−
537− emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE;
538−
539− return 1;
540− }
541−
542− return yaml_emitter_set_emitter_error(emitter,
543− "expected STREAM-START");
544−}
545−
546−/*
547− * Expect DOCUMENT-START or STREAM-END.
548− */
549−
550−static int
551−yaml_emitter_emit_document_start(yaml_emitter_t *emitter,
552− yaml_event_t *event, int first)
553−{
554− if (event->type == YAML_DOCUMENT_START_EVENT)
555− {
556− yaml_tag_directive_t default_tag_directives[] = {
557− {(yaml_char_t *)"!", (yaml_char_t *)"!"},
558− {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
559− {NULL, NULL}
560− };
561− yaml_tag_directive_t *tag_directive;
562− int implicit;
563−
564− if (event->data.document_start.version_directive) {
565− if (!yaml_emitter_analyze_version_directive(emitter,
566− *event->data.document_start.version_directive))
567− return 0;
568− }
569−
570− for (tag_directive = event->data.document_start.tag_directives.start;
571− tag_directive != event->data.document_start.tag_directives.end;
572− tag_directive ++) {
573− if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive))
574− return 0;
575− if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0))
576− return 0;
577− }
578−
579− for (tag_directive = default_tag_directives;
580− tag_directive->handle; tag_directive ++) {
581− if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1))
582− return 0;
583− }
584−
585− implicit = event->data.document_start.implicit;
586− if (!first || emitter->canonical) {
587− implicit = 0;
588− }
589−
590− if ((event->data.document_start.version_directive ||
591− (event->data.document_start.tag_directives.start
592− != event->data.document_start.tag_directives.end)) &&
593− emitter->open_ended)
594− {
595− if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
596− return 0;
597− if (!yaml_emitter_write_indent(emitter))
598− return 0;
599− }
600−
601− if (event->data.document_start.version_directive) {
602− implicit = 0;
603− if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0))
604− return 0;
605− if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0))
606− return 0;
607− if (!yaml_emitter_write_indent(emitter))
608− return 0;
609− }
610−
611− if (event->data.document_start.tag_directives.start
612− != event->data.document_start.tag_directives.end) {
613− implicit = 0;
614− for (tag_directive = event->data.document_start.tag_directives.start;
615− tag_directive != event->data.document_start.tag_directives.end;
616− tag_directive ++) {
617− if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0))
618− return 0;
619− if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle,
620− strlen((char *)tag_directive->handle)))
621− return 0;
622− if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix,
623− strlen((char *)tag_directive->prefix), 1))
624− return 0;
625− if (!yaml_emitter_write_indent(emitter))
626− return 0;
627− }
628− }
629−
630− if (yaml_emitter_check_empty_document(emitter)) {
631− implicit = 0;
632− }
633−
634− if (!implicit) {
635− if (!yaml_emitter_write_indent(emitter))
636− return 0;
637− if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0))
638− return 0;
639− if (emitter->canonical) {
640− if (!yaml_emitter_write_indent(emitter))
641− return 0;
642− }
643− }
644−
645− emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
646−
647− return 1;
648− }
649−
650− else if (event->type == YAML_STREAM_END_EVENT)
651− {
652− if (emitter->open_ended)
653− {
654− if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
655− return 0;
656− if (!yaml_emitter_write_indent(emitter))
657− return 0;
658− }
659−
660− if (!yaml_emitter_flush(emitter))
661− return 0;
662−
663− emitter->state = YAML_EMIT_END_STATE;
664−
665− return 1;
666− }
667−
668− return yaml_emitter_set_emitter_error(emitter,
669− "expected DOCUMENT-START or STREAM-END");
670−}
671−
672−/*
673− * Expect the root node.
674− */
675−
676−static int
677−yaml_emitter_emit_document_content(yaml_emitter_t *emitter,
678− yaml_event_t *event)
679−{
680− if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE))
681− return 0;
682−
683− return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0);
684−}
685−
686−/*
687− * Expect DOCUMENT-END.
688− */
689−
690−static int
691−yaml_emitter_emit_document_end(yaml_emitter_t *emitter,
692− yaml_event_t *event)
693−{
694− if (event->type == YAML_DOCUMENT_END_EVENT)
695− {
696− if (!yaml_emitter_write_indent(emitter))
697− return 0;
698− if (!event->data.document_end.implicit) {
699− if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0))
700− return 0;
701− if (!yaml_emitter_write_indent(emitter))
702− return 0;
703− }
704− if (!yaml_emitter_flush(emitter))
705− return 0;
706−
707− emitter->state = YAML_EMIT_DOCUMENT_START_STATE;
708−
709− while (!STACK_EMPTY(emitter, emitter->tag_directives)) {
710− yaml_tag_directive_t tag_directive = POP(emitter,
711− emitter->tag_directives);
712− yaml_free(tag_directive.handle);
713− yaml_free(tag_directive.prefix);
714− }
715−
716− return 1;
717− }
718−
719− return yaml_emitter_set_emitter_error(emitter,
720− "expected DOCUMENT-END");
721−}
722−
723−/*
724− *
725− * Expect a flow item node.
726− */
727−
728−static int
729−yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter,
730− yaml_event_t *event, int first)
731−{
732− if (first)
733− {
734− if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0))
735− return 0;
736− if (!yaml_emitter_increase_indent(emitter, 1, 0))
737− return 0;
738− emitter->flow_level ++;
739− }
740−
741− if (event->type == YAML_SEQUENCE_END_EVENT)
742− {
743− emitter->flow_level --;
744− emitter->indent = POP(emitter, emitter->indents);
745− if (emitter->canonical && !first) {
746− if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
747− return 0;
748− if (!yaml_emitter_write_indent(emitter))
749− return 0;
750− }
751− if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0))
752− return 0;
753− emitter->state = POP(emitter, emitter->states);
754−
755− return 1;
756− }
757−
758− if (!first) {
759− if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
760− return 0;
761− }
762−
763− if (emitter->canonical || emitter->column > emitter->best_width) {
764− if (!yaml_emitter_write_indent(emitter))
765− return 0;
766− }
767− if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE))
768− return 0;
769−
770− return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
771−}
772−
773−/*
774− * Expect a flow key node.
775− */
776−
777−static int
778−yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter,
779− yaml_event_t *event, int first)
780−{
781− if (first)
782− {
783− if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0))
784− return 0;
785− if (!yaml_emitter_increase_indent(emitter, 1, 0))
786− return 0;
787− emitter->flow_level ++;
788− }
789−
790− if (event->type == YAML_MAPPING_END_EVENT)
791− {
792− emitter->flow_level --;
793− emitter->indent = POP(emitter, emitter->indents);
794− if (emitter->canonical && !first) {
795− if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
796− return 0;
797− if (!yaml_emitter_write_indent(emitter))
798− return 0;
799− }
800− if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0))
801− return 0;
802− emitter->state = POP(emitter, emitter->states);
803−
804− return 1;
805− }
806−
807− if (!first) {
808− if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0))
809− return 0;
810− }
811− if (emitter->canonical || emitter->column > emitter->best_width) {
812− if (!yaml_emitter_write_indent(emitter))
813− return 0;
814− }
815−
816− if (!emitter->canonical && yaml_emitter_check_simple_key(emitter))
817− {
818− if (!PUSH(emitter, emitter->states,
819− YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE))
820− return 0;
821−
822− return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
823− }
824− else
825− {
826− if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0))
827− return 0;
828− if (!PUSH(emitter, emitter->states,
829− YAML_EMIT_FLOW_MAPPING_VALUE_STATE))
830− return 0;
831−
832− return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
833− }
834−}
835−
836−/*
837− * Expect a flow value node.
838− */
839−
840−static int
841−yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter,
842− yaml_event_t *event, int simple)
843−{
844− if (simple) {
845− if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
846− return 0;
847− }
848− else {
849− if (emitter->canonical || emitter->column > emitter->best_width) {
850− if (!yaml_emitter_write_indent(emitter))
851− return 0;
852− }
853− if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0))
854− return 0;
855− }
856− if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE))
857− return 0;
858− return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
859−}
860−
861−/*
862− * Expect a block item node.
863− */
864−
865−static int
866−yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter,
867− yaml_event_t *event, int first)
868−{
869− if (first)
870− {
871− if (!yaml_emitter_increase_indent(emitter, 0,
872− (emitter->mapping_context && !emitter->indention)))
873− return 0;
874− }
875−
876− if (event->type == YAML_SEQUENCE_END_EVENT)
877− {
878− emitter->indent = POP(emitter, emitter->indents);
879− emitter->state = POP(emitter, emitter->states);
880−
881− return 1;
882− }
883−
884− if (!yaml_emitter_write_indent(emitter))
885− return 0;
886− if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1))
887− return 0;
888− if (!PUSH(emitter, emitter->states,
889− YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE))
890− return 0;
891−
892− return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0);
893−}
894−
895−/*
896− * Expect a block key node.
897− */
898−
899−static int
900−yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter,
901− yaml_event_t *event, int first)
902−{
903− if (first)
904− {
905− if (!yaml_emitter_increase_indent(emitter, 0, 0))
906− return 0;
907− }
908−
909− if (event->type == YAML_MAPPING_END_EVENT)
910− {
911− emitter->indent = POP(emitter, emitter->indents);
912− emitter->state = POP(emitter, emitter->states);
913−
914− return 1;
915− }
916−
917− if (!yaml_emitter_write_indent(emitter))
918− return 0;
919−
920− if (yaml_emitter_check_simple_key(emitter))
921− {
922− if (!PUSH(emitter, emitter->states,
923− YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE))
924− return 0;
925−
926− return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1);
927− }
928− else
929− {
930− if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1))
931− return 0;
932− if (!PUSH(emitter, emitter->states,
933− YAML_EMIT_BLOCK_MAPPING_VALUE_STATE))
934− return 0;
935−
936− return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
937− }
938−}
939−
940−/*
941− * Expect a block value node.
942− */
943−
944−static int
945−yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter,
946− yaml_event_t *event, int simple)
947−{
948− if (simple) {
949− if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0))
950− return 0;
951− }
952− else {
953− if (!yaml_emitter_write_indent(emitter))
954− return 0;
955− if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1))
956− return 0;
957− }
958− if (!PUSH(emitter, emitter->states,
959− YAML_EMIT_BLOCK_MAPPING_KEY_STATE))
960− return 0;
961−
962− return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0);
963−}
964−
965−/*
966− * Expect a node.
967− */
968−
969−static int
970−yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event,
971− int root, int sequence, int mapping, int simple_key)
972−{
973− emitter->root_context = root;
974− emitter->sequence_context = sequence;
975− emitter->mapping_context = mapping;
976− emitter->simple_key_context = simple_key;
977−
978− switch (event->type)
979− {
980− case YAML_ALIAS_EVENT:
981− return yaml_emitter_emit_alias(emitter, event);
982−
983− case YAML_SCALAR_EVENT:
984− return yaml_emitter_emit_scalar(emitter, event);
985−
986− case YAML_SEQUENCE_START_EVENT:
987− return yaml_emitter_emit_sequence_start(emitter, event);
988−
989− case YAML_MAPPING_START_EVENT:
990− return yaml_emitter_emit_mapping_start(emitter, event);
991−
992− default:
993− return yaml_emitter_set_emitter_error(emitter,
994− "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS");
995− }
996−
997− return 0;
998−}
999−
1000−/*
1001− * Expect ALIAS.
1002− */
1003−
1004−static int
1005−yaml_emitter_emit_alias(yaml_emitter_t *emitter, SHIM(yaml_event_t *event))
1006−{
1007− if (!yaml_emitter_process_anchor(emitter))
1008− return 0;
1009− emitter->state = POP(emitter, emitter->states);
1010−
1011− return 1;
1012−}
1013−
1014−/*
1015− * Expect SCALAR.
1016− */
1017−
1018−static int
1019−yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event)
1020−{
1021− if (!yaml_emitter_select_scalar_style(emitter, event))
1022− return 0;
1023− if (!yaml_emitter_process_anchor(emitter))
1024− return 0;
1025− if (!yaml_emitter_process_tag(emitter))
1026− return 0;
1027− if (!yaml_emitter_increase_indent(emitter, 1, 0))
1028− return 0;
1029− if (!yaml_emitter_process_scalar(emitter))
1030− return 0;
1031− emitter->indent = POP(emitter, emitter->indents);
1032− emitter->state = POP(emitter, emitter->states);
1033−
1034− return 1;
1035−}
1036−
1037−/*
1038− * Expect SEQUENCE-START.
1039− */
1040−
1041−static int
1042−yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event)
1043−{
1044− if (!yaml_emitter_process_anchor(emitter))
1045− return 0;
1046− if (!yaml_emitter_process_tag(emitter))
1047− return 0;
1048−
1049− if (emitter->flow_level || emitter->canonical
1050− || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
1051− || yaml_emitter_check_empty_sequence(emitter)) {
1052− emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE;
1053− }
1054− else {
1055− emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE;
1056− }
1057−
1058− return 1;
1059−}
1060−
1061−/*
1062− * Expect MAPPING-START.
1063− */
1064−
1065−static int
1066−yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event)
1067−{
1068− if (!yaml_emitter_process_anchor(emitter))
1069− return 0;
1070− if (!yaml_emitter_process_tag(emitter))
1071− return 0;
1072−
1073− if (emitter->flow_level || emitter->canonical
1074− || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
1075− || yaml_emitter_check_empty_mapping(emitter)) {
1076− emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
1077− }
1078− else {
1079− emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
1080− }
1081−
1082− return 1;
1083−}
1084−
1085−/*
1086− * Check if the document content is an empty scalar.
1087− */
1088−
1089−static int
1090−yaml_emitter_check_empty_document(SHIM(yaml_emitter_t *emitter))
1091−{
1092− return 0;
1093−}
1094−
1095−/*
1096− * Check if the next events represent an empty sequence.
1097− */
1098−
1099−static int
1100−yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter)
1101−{
1102− if (emitter->events.tail - emitter->events.head < 2)
1103− return 0;
1104−
1105− return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT
1106− && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT);
1107−}
1108−
1109−/*
1110− * Check if the next events represent an empty mapping.
1111− */
1112−
1113−static int
1114−yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter)
1115−{
1116− if (emitter->events.tail - emitter->events.head < 2)
1117− return 0;
1118−
1119− return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT
1120− && emitter->events.head[1].type == YAML_MAPPING_END_EVENT);
1121−}
1122−
1123−/*
1124− * Check if the next node can be expressed as a simple key.
1125− */
1126−
1127−static int
1128−yaml_emitter_check_simple_key(yaml_emitter_t *emitter)
1129−{
1130− yaml_event_t *event = emitter->events.head;
1131− size_t length = 0;
1132−
1133− switch (event->type)
1134− {
1135− case YAML_ALIAS_EVENT:
1136− length += emitter->anchor_data.anchor_length;
1137− break;
1138−
1139− case YAML_SCALAR_EVENT:
1140− if (emitter->scalar_data.multiline)
1141− return 0;
1142− length += emitter->anchor_data.anchor_length
1143− + emitter->tag_data.handle_length
1144− + emitter->tag_data.suffix_length
1145− + emitter->scalar_data.length;
1146− break;
1147−
1148− case YAML_SEQUENCE_START_EVENT:
1149− if (!yaml_emitter_check_empty_sequence(emitter))
1150− return 0;
1151− length += emitter->anchor_data.anchor_length
1152− + emitter->tag_data.handle_length
1153− + emitter->tag_data.suffix_length;
1154− break;
1155−
1156− case YAML_MAPPING_START_EVENT:
1157− if (!yaml_emitter_check_empty_mapping(emitter))
1158− return 0;
1159− length += emitter->anchor_data.anchor_length
1160− + emitter->tag_data.handle_length
1161− + emitter->tag_data.suffix_length;
1162− break;
1163−
1164− default:
1165− return 0;
1166− }
1167−
1168− if (length > 128)
1169− return 0;
1170−
1171− return 1;
1172−}
1173−
1174−/*
1175− * Determine an acceptable scalar style.
1176− */
1177−
1178−static int
1179−yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event)
1180−{
1181− yaml_scalar_style_t style = event->data.scalar.style;
1182− int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix);
1183−
1184− if (no_tag && !event->data.scalar.plain_implicit
1185− && !event->data.scalar.quoted_implicit) {
1186− return yaml_emitter_set_emitter_error(emitter,
1187− "neither tag nor implicit flags are specified");
1188− }
1189−
1190− if (style == YAML_ANY_SCALAR_STYLE)
1191− style = YAML_PLAIN_SCALAR_STYLE;
1192−
1193− if (emitter->canonical)
1194− style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1195−
1196− if (emitter->simple_key_context && emitter->scalar_data.multiline)
1197− style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1198−
1199− if (style == YAML_PLAIN_SCALAR_STYLE)
1200− {
1201− if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed)
1202− || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed))
1203− style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1204− if (!emitter->scalar_data.length
1205− && (emitter->flow_level || emitter->simple_key_context))
1206− style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1207− if (no_tag && !event->data.scalar.plain_implicit)
1208− style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
1209− }
1210−
1211− if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE)
1212− {
1213− if (!emitter->scalar_data.single_quoted_allowed)
1214− style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1215− }
1216−
1217− if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE)
1218− {
1219− if (!emitter->scalar_data.block_allowed
1220− || emitter->flow_level || emitter->simple_key_context)
1221− style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
1222− }
1223−
1224− if (no_tag && !event->data.scalar.quoted_implicit
1225− && style != YAML_PLAIN_SCALAR_STYLE)
1226− {
1227− emitter->tag_data.handle = (yaml_char_t *)"!";
1228− emitter->tag_data.handle_length = 1;
1229− }
1230−
1231− emitter->scalar_data.style = style;
1232−
1233− return 1;
1234−}
1235−
1236−/*
1237− * Write an achor.
1238− */
1239−
1240−static int
1241−yaml_emitter_process_anchor(yaml_emitter_t *emitter)
1242−{
1243− if (!emitter->anchor_data.anchor)
1244− return 1;
1245−
1246− if (!yaml_emitter_write_indicator(emitter,
1247− (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0))
1248− return 0;
1249−
1250− return yaml_emitter_write_anchor(emitter,
1251− emitter->anchor_data.anchor, emitter->anchor_data.anchor_length);
1252−}
1253−
1254−/*
1255− * Write a tag.
1256− */
1257−
1258−static int
1259−yaml_emitter_process_tag(yaml_emitter_t *emitter)
1260−{
1261− if (!emitter->tag_data.handle && !emitter->tag_data.suffix)
1262− return 1;
1263−
1264− if (emitter->tag_data.handle)
1265− {
1266− if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle,
1267− emitter->tag_data.handle_length))
1268− return 0;
1269− if (emitter->tag_data.suffix) {
1270− if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1271− emitter->tag_data.suffix_length, 0))
1272− return 0;
1273− }
1274− }
1275− else
1276− {
1277− if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0))
1278− return 0;
1279− if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix,
1280− emitter->tag_data.suffix_length, 0))
1281− return 0;
1282− if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0))
1283− return 0;
1284− }
1285−
1286− return 1;
1287−}
1288−
1289−/*
1290− * Write a scalar.
1291− */
1292−
1293−static int
1294−yaml_emitter_process_scalar(yaml_emitter_t *emitter)
1295−{
1296− switch (emitter->scalar_data.style)
1297− {
1298− case YAML_PLAIN_SCALAR_STYLE:
1299− return yaml_emitter_write_plain_scalar(emitter,
1300− emitter->scalar_data.value, emitter->scalar_data.length,
1301− !emitter->simple_key_context);
1302−
1303− case YAML_SINGLE_QUOTED_SCALAR_STYLE:
1304− return yaml_emitter_write_single_quoted_scalar(emitter,
1305− emitter->scalar_data.value, emitter->scalar_data.length,
1306− !emitter->simple_key_context);
1307−
1308− case YAML_DOUBLE_QUOTED_SCALAR_STYLE:
1309− return yaml_emitter_write_double_quoted_scalar(emitter,
1310− emitter->scalar_data.value, emitter->scalar_data.length,
1311− !emitter->simple_key_context);
1312−
1313− case YAML_LITERAL_SCALAR_STYLE:
1314− return yaml_emitter_write_literal_scalar(emitter,
1315− emitter->scalar_data.value, emitter->scalar_data.length);
1316−
1317− case YAML_FOLDED_SCALAR_STYLE:
1318− return yaml_emitter_write_folded_scalar(emitter,
1319− emitter->scalar_data.value, emitter->scalar_data.length);
1320−
1321− default:
1322− assert(1); /* Impossible. */
1323− }
1324−
1325− return 0;
1326−}
1327−
1328−/*
1329− * Check if a %YAML directive is valid.
1330− */
1331−
1332−static int
1333−yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter,
1334− yaml_version_directive_t version_directive)
1335−{
1336− if (version_directive.major != 1 || version_directive.minor != 1) {
1337− return yaml_emitter_set_emitter_error(emitter,
1338− "incompatible %YAML directive");
1339− }
1340−
1341− return 1;
1342−}
1343−
1344−/*
1345− * Check if a %TAG directive is valid.
1346− */
1347−
1348−static int
1349−yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter,
1350− yaml_tag_directive_t tag_directive)
1351−{
1352− yaml_string_t handle;
1353− yaml_string_t prefix;
1354− size_t handle_length;
1355− size_t prefix_length;
1356−
1357− handle_length = strlen((char *)tag_directive.handle);
1358− prefix_length = strlen((char *)tag_directive.prefix);
1359− STRING_ASSIGN(handle, tag_directive.handle, handle_length);
1360− STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length);
1361−
1362− if (handle.start == handle.end) {
1363− return yaml_emitter_set_emitter_error(emitter,
1364− "tag handle must not be empty");
1365− }
1366−
1367− if (handle.start[0] != '!') {
1368− return yaml_emitter_set_emitter_error(emitter,
1369− "tag handle must start with '!'");
1370− }
1371−
1372− if (handle.end[-1] != '!') {
1373− return yaml_emitter_set_emitter_error(emitter,
1374− "tag handle must end with '!'");
1375− }
1376−
1377− handle.pointer ++;
1378−
1379− while (handle.pointer < handle.end-1) {
1380− if (!IS_ALPHA(handle)) {
1381− return yaml_emitter_set_emitter_error(emitter,
1382− "tag handle must contain alphanumerical characters only");
1383− }
1384− MOVE(handle);
1385− }
1386−
1387− if (prefix.start == prefix.end) {
1388− return yaml_emitter_set_emitter_error(emitter,
1389− "tag prefix must not be empty");
1390− }
1391−
1392− return 1;
1393−}
1394−
1395−/*
1396− * Check if an anchor is valid.
1397− */
1398−
1399−static int
1400−yaml_emitter_analyze_anchor(yaml_emitter_t *emitter,
1401− yaml_char_t *anchor, int alias)
1402−{
1403− size_t anchor_length;
1404− yaml_string_t string;
1405−
1406− anchor_length = strlen((char *)anchor);
1407− STRING_ASSIGN(string, anchor, anchor_length);
1408−
1409− if (string.start == string.end) {
1410− return yaml_emitter_set_emitter_error(emitter, alias ?
1411− "alias value must not be empty" :
1412− "anchor value must not be empty");
1413− }
1414−
1415− while (string.pointer != string.end) {
1416− if (!IS_ALPHA(string)) {
1417− return yaml_emitter_set_emitter_error(emitter, alias ?
1418− "alias value must contain alphanumerical characters only" :
1419− "anchor value must contain alphanumerical characters only");
1420− }
1421− MOVE(string);
1422− }
1423−
1424− emitter->anchor_data.anchor = string.start;
1425− emitter->anchor_data.anchor_length = string.end - string.start;
1426− emitter->anchor_data.alias = alias;
1427−
1428− return 1;
1429−}
1430−
1431−/*
1432− * Check if a tag is valid.
1433− */
1434−
1435−static int
1436−yaml_emitter_analyze_tag(yaml_emitter_t *emitter,
1437− yaml_char_t *tag)
1438−{
1439− size_t tag_length;
1440− yaml_string_t string;
1441− yaml_tag_directive_t *tag_directive;
1442−
1443− tag_length = strlen((char *)tag);
1444− STRING_ASSIGN(string, tag, tag_length);
1445−
1446− if (string.start == string.end) {
1447− return yaml_emitter_set_emitter_error(emitter,
1448− "tag value must not be empty");
1449− }
1450−
1451− for (tag_directive = emitter->tag_directives.start;
1452− tag_directive != emitter->tag_directives.top; tag_directive ++) {
1453− size_t prefix_length = strlen((char *)tag_directive->prefix);
1454− if (prefix_length < (size_t)(string.end - string.start)
1455− && strncmp((char *)tag_directive->prefix, (char *)string.start,
1456− prefix_length) == 0)
1457− {
1458− emitter->tag_data.handle = tag_directive->handle;
1459− emitter->tag_data.handle_length =
1460− strlen((char *)tag_directive->handle);
1461− emitter->tag_data.suffix = string.start + prefix_length;
1462− emitter->tag_data.suffix_length =
1463− (string.end - string.start) - prefix_length;
1464− return 1;
1465− }
1466− }
1467−
1468− emitter->tag_data.suffix = string.start;
1469− emitter->tag_data.suffix_length = string.end - string.start;
1470−
1471− return 1;
1472−}
1473−
1474−/*
1475− * Check if a scalar is valid.
1476− */
1477−
1478−static int
1479−yaml_emitter_analyze_scalar(yaml_emitter_t *emitter,
1480− yaml_char_t *value, size_t length)
1481−{
1482− yaml_string_t string;
1483−
1484− int block_indicators = 0;
1485− int flow_indicators = 0;
1486− int line_breaks = 0;
1487− int special_characters = 0;
1488−
1489− int leading_space = 0;
1490− int leading_break = 0;
1491− int trailing_space = 0;
1492− int trailing_break = 0;
1493− int break_space = 0;
1494− int space_break = 0;
1495−
1496− int preceded_by_whitespace = 0;
1497− int followed_by_whitespace = 0;
1498− int previous_space = 0;
1499− int previous_break = 0;
1500−
1501− STRING_ASSIGN(string, value, length);
1502−
1503− emitter->scalar_data.value = value;
1504− emitter->scalar_data.length = length;
1505−
1506− if (string.start == string.end)
1507− {
1508− emitter->scalar_data.multiline = 0;
1509− emitter->scalar_data.flow_plain_allowed = 0;
1510− emitter->scalar_data.block_plain_allowed = 1;
1511− emitter->scalar_data.single_quoted_allowed = 1;
1512− emitter->scalar_data.block_allowed = 0;
1513−
1514− return 1;
1515− }
1516−
1517− if ((CHECK_AT(string, '-', 0)
1518− && CHECK_AT(string, '-', 1)
1519− && CHECK_AT(string, '-', 2))
1520− || (CHECK_AT(string, '.', 0)
1521− && CHECK_AT(string, '.', 1)
1522− && CHECK_AT(string, '.', 2))) {
1523− block_indicators = 1;
1524− flow_indicators = 1;
1525− }
1526−
1527− preceded_by_whitespace = 1;
1528− followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
1529−
1530− while (string.pointer != string.end)
1531− {
1532− if (string.start == string.pointer)
1533− {
1534− if (CHECK(string, '#') || CHECK(string, ',')
1535− || CHECK(string, '[') || CHECK(string, ']')
1536− || CHECK(string, '{') || CHECK(string, '}')
1537− || CHECK(string, '&') || CHECK(string, '*')
1538− || CHECK(string, '!') || CHECK(string, '|')
1539− || CHECK(string, '>') || CHECK(string, '\'')
1540− || CHECK(string, '"') || CHECK(string, '%')
1541− || CHECK(string, '@') || CHECK(string, '`')) {
1542− flow_indicators = 1;
1543− block_indicators = 1;
1544− }
1545−
1546− if (CHECK(string, '?') || CHECK(string, ':')) {
1547− flow_indicators = 1;
1548− if (followed_by_whitespace) {
1549− block_indicators = 1;
1550− }
1551− }
1552−
1553− if (CHECK(string, '-') && followed_by_whitespace) {
1554− flow_indicators = 1;
1555− block_indicators = 1;
1556− }
1557− }
1558− else
1559− {
1560− if (CHECK(string, ',') || CHECK(string, '?')
1561− || CHECK(string, '[') || CHECK(string, ']')
1562− || CHECK(string, '{') || CHECK(string, '}')) {
1563− flow_indicators = 1;
1564− }
1565−
1566− if (CHECK(string, ':')) {
1567− flow_indicators = 1;
1568− if (followed_by_whitespace) {
1569− block_indicators = 1;
1570− }
1571− }
1572−
1573− if (CHECK(string, '#') && preceded_by_whitespace) {
1574− flow_indicators = 1;
1575− block_indicators = 1;
1576− }
1577− }
1578−
1579− if (!IS_PRINTABLE(string)
1580− || (!IS_ASCII(string) && !emitter->unicode)) {
1581− special_characters = 1;
1582− }
1583−
1584− if (IS_BREAK(string)) {
1585− line_breaks = 1;
1586− }
1587−
1588− if (IS_SPACE(string))
1589− {
1590− if (string.start == string.pointer) {
1591− leading_space = 1;
1592− }
1593− if (string.pointer+WIDTH(string) == string.end) {
1594− trailing_space = 1;
1595− }
1596− if (previous_break) {
1597− break_space = 1;
1598− }
1599− previous_space = 1;
1600− previous_break = 0;
1601− }
1602− else if (IS_BREAK(string))
1603− {
1604− if (string.start == string.pointer) {
1605− leading_break = 1;
1606− }
1607− if (string.pointer+WIDTH(string) == string.end) {
1608− trailing_break = 1;
1609− }
1610− if (previous_space) {
1611− space_break = 1;
1612− }
1613− previous_space = 0;
1614− previous_break = 1;
1615− }
1616− else
1617− {
1618− previous_space = 0;
1619− previous_break = 0;
1620− }
1621−
1622− preceded_by_whitespace = IS_BLANKZ(string);
1623− MOVE(string);
1624− if (string.pointer != string.end) {
1625− followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string));
1626− }
1627− }
1628−
1629− emitter->scalar_data.multiline = line_breaks;
1630−
1631− emitter->scalar_data.flow_plain_allowed = 1;
1632− emitter->scalar_data.block_plain_allowed = 1;
1633− emitter->scalar_data.single_quoted_allowed = 1;
1634− emitter->scalar_data.block_allowed = 1;
1635−
1636− if (leading_space || leading_break || trailing_space || trailing_break) {
1637− emitter->scalar_data.flow_plain_allowed = 0;
1638− emitter->scalar_data.block_plain_allowed = 0;
1639− }
1640−
1641− if (trailing_space) {
1642− emitter->scalar_data.block_allowed = 0;
1643− }
1644−
1645− if (break_space) {
1646− emitter->scalar_data.flow_plain_allowed = 0;
1647− emitter->scalar_data.block_plain_allowed = 0;
1648− emitter->scalar_data.single_quoted_allowed = 0;
1649− }
1650−
1651− if (space_break || special_characters) {
1652− emitter->scalar_data.flow_plain_allowed = 0;
1653− emitter->scalar_data.block_plain_allowed = 0;
1654− emitter->scalar_data.single_quoted_allowed = 0;
1655− emitter->scalar_data.block_allowed = 0;
1656− }
1657−
1658− if (line_breaks) {
1659− emitter->scalar_data.flow_plain_allowed = 0;
1660− emitter->scalar_data.block_plain_allowed = 0;
1661− }
1662−
1663− if (flow_indicators) {
1664− emitter->scalar_data.flow_plain_allowed = 0;
1665− }
1666−
1667− if (block_indicators) {
1668− emitter->scalar_data.block_plain_allowed = 0;
1669− }
1670−
1671− return 1;
1672−}
1673−
1674−/*
1675− * Check if the event data is valid.
1676− */
1677−
1678−static int
1679−yaml_emitter_analyze_event(yaml_emitter_t *emitter,
1680− yaml_event_t *event)
1681−{
1682− emitter->anchor_data.anchor = NULL;
1683− emitter->anchor_data.anchor_length = 0;
1684− emitter->tag_data.handle = NULL;
1685− emitter->tag_data.handle_length = 0;
1686− emitter->tag_data.suffix = NULL;
1687− emitter->tag_data.suffix_length = 0;
1688− emitter->scalar_data.value = NULL;
1689− emitter->scalar_data.length = 0;
1690−
1691− switch (event->type)
1692− {
1693− case YAML_ALIAS_EVENT:
1694− if (!yaml_emitter_analyze_anchor(emitter,
1695− event->data.alias.anchor, 1))
1696− return 0;
1697− return 1;
1698−
1699− case YAML_SCALAR_EVENT:
1700− if (event->data.scalar.anchor) {
1701− if (!yaml_emitter_analyze_anchor(emitter,
1702− event->data.scalar.anchor, 0))
1703− return 0;
1704− }
1705− if (event->data.scalar.tag && (emitter->canonical ||
1706− (!event->data.scalar.plain_implicit
1707− && !event->data.scalar.quoted_implicit))) {
1708− if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag))
1709− return 0;
1710− }
1711− if (!yaml_emitter_analyze_scalar(emitter,
1712− event->data.scalar.value, event->data.scalar.length))
1713− return 0;
1714− return 1;
1715−
1716− case YAML_SEQUENCE_START_EVENT:
1717− if (event->data.sequence_start.anchor) {
1718− if (!yaml_emitter_analyze_anchor(emitter,
1719− event->data.sequence_start.anchor, 0))
1720− return 0;
1721− }
1722− if (event->data.sequence_start.tag && (emitter->canonical ||
1723− !event->data.sequence_start.implicit)) {
1724− if (!yaml_emitter_analyze_tag(emitter,
1725− event->data.sequence_start.tag))
1726− return 0;
1727− }
1728− return 1;
1729−
1730− case YAML_MAPPING_START_EVENT:
1731− if (event->data.mapping_start.anchor) {
1732− if (!yaml_emitter_analyze_anchor(emitter,
1733− event->data.mapping_start.anchor, 0))
1734− return 0;
1735− }
1736− if (event->data.mapping_start.tag && (emitter->canonical ||
1737− !event->data.mapping_start.implicit)) {
1738− if (!yaml_emitter_analyze_tag(emitter,
1739− event->data.mapping_start.tag))
1740− return 0;
1741− }
1742− return 1;
1743−
1744− default:
1745− return 1;
1746− }
1747−}
1748−
1749−/*
1750− * Write the BOM character.
1751− */
1752−
1753−static int
1754−yaml_emitter_write_bom(yaml_emitter_t *emitter)
1755−{
1756− if (!FLUSH(emitter)) return 0;
1757−
1758− *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF';
1759− *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB';
1760− *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF';
1761−
1762− return 1;
1763−}
1764−
1765−static int
1766−yaml_emitter_write_indent(yaml_emitter_t *emitter)
1767−{
1768− int indent = (emitter->indent >= 0) ? emitter->indent : 0;
1769−
1770− if (!emitter->indention || emitter->column > indent
1771− || (emitter->column == indent && !emitter->whitespace)) {
1772− if (!PUT_BREAK(emitter)) return 0;
1773− }
1774−
1775− while (emitter->column < indent) {
1776− if (!PUT(emitter, ' ')) return 0;
1777− }
1778−
1779− emitter->whitespace = 1;
1780− emitter->indention = 1;
1781−
1782− return 1;
1783−}
1784−
1785−static int
1786−yaml_emitter_write_indicator(yaml_emitter_t *emitter,
1787− char *indicator, int need_whitespace,
1788− int is_whitespace, int is_indention)
1789−{
1790− size_t indicator_length;
1791− yaml_string_t string;
1792−
1793− indicator_length = strlen(indicator);
1794− STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length);
1795−
1796− if (need_whitespace && !emitter->whitespace) {
1797− if (!PUT(emitter, ' ')) return 0;
1798− }
1799−
1800− while (string.pointer != string.end) {
1801− if (!WRITE(emitter, string)) return 0;
1802− }
1803−
1804− emitter->whitespace = is_whitespace;
1805− emitter->indention = (emitter->indention && is_indention);
1806− emitter->open_ended = 0;
1807−
1808− return 1;
1809−}
1810−
1811−static int
1812−yaml_emitter_write_anchor(yaml_emitter_t *emitter,
1813− yaml_char_t *value, size_t length)
1814−{
1815− yaml_string_t string;
1816− STRING_ASSIGN(string, value, length);
1817−
1818− while (string.pointer != string.end) {
1819− if (!WRITE(emitter, string)) return 0;
1820− }
1821−
1822− emitter->whitespace = 0;
1823− emitter->indention = 0;
1824−
1825− return 1;
1826−}
1827−
1828−static int
1829−yaml_emitter_write_tag_handle(yaml_emitter_t *emitter,
1830− yaml_char_t *value, size_t length)
1831−{
1832− yaml_string_t string;
1833− STRING_ASSIGN(string, value, length);
1834−
1835− if (!emitter->whitespace) {
1836− if (!PUT(emitter, ' ')) return 0;
1837− }
1838−
1839− while (string.pointer != string.end) {
1840− if (!WRITE(emitter, string)) return 0;
1841− }
1842−
1843− emitter->whitespace = 0;
1844− emitter->indention = 0;
1845−
1846− return 1;
1847−}
1848−
1849−static int
1850−yaml_emitter_write_tag_content(yaml_emitter_t *emitter,
1851− yaml_char_t *value, size_t length,
1852− int need_whitespace)
1853−{
1854− yaml_string_t string;
1855− STRING_ASSIGN(string, value, length);
1856−
1857− if (need_whitespace && !emitter->whitespace) {
1858− if (!PUT(emitter, ' ')) return 0;
1859− }
1860−
1861− while (string.pointer != string.end) {
1862− if (IS_ALPHA(string)
1863− || CHECK(string, ';') || CHECK(string, '/')
1864− || CHECK(string, '?') || CHECK(string, ':')
1865− || CHECK(string, '@') || CHECK(string, '&')
1866− || CHECK(string, '=') || CHECK(string, '+')
1867− || CHECK(string, '$') || CHECK(string, ',')
1868− || CHECK(string, '_') || CHECK(string, '.')
1869− || CHECK(string, '~') || CHECK(string, '*')
1870− || CHECK(string, '\'') || CHECK(string, '(')
1871− || CHECK(string, ')') || CHECK(string, '[')
1872− || CHECK(string, ']')) {
1873− if (!WRITE(emitter, string)) return 0;
1874− }
1875− else {
1876− int width = WIDTH(string);
1877− unsigned int value;
1878− while (width --) {
1879− value = *(string.pointer++);
1880− if (!PUT(emitter, '%')) return 0;
1881− if (!PUT(emitter, (value >> 4)
1882− + ((value >> 4) < 10 ? '0' : 'A' - 10)))
1883− return 0;
1884− if (!PUT(emitter, (value & 0x0F)
1885− + ((value & 0x0F) < 10 ? '0' : 'A' - 10)))
1886− return 0;
1887− }
1888− }
1889− }
1890−
1891− emitter->whitespace = 0;
1892− emitter->indention = 0;
1893−
1894− return 1;
1895−}
1896−
1897−static int
1898−yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter,
1899− yaml_char_t *value, size_t length, int allow_breaks)
1900−{
1901− yaml_string_t string;
1902− int spaces = 0;
1903− int breaks = 0;
1904−
1905− STRING_ASSIGN(string, value, length);
1906−
1907− if (!emitter->whitespace) {
1908− if (!PUT(emitter, ' ')) return 0;
1909− }
1910−
1911− while (string.pointer != string.end)
1912− {
1913− if (IS_SPACE(string))
1914− {
1915− if (allow_breaks && !spaces
1916− && emitter->column > emitter->best_width
1917− && !IS_SPACE_AT(string, 1)) {
1918− if (!yaml_emitter_write_indent(emitter)) return 0;
1919− MOVE(string);
1920− }
1921− else {
1922− if (!WRITE(emitter, string)) return 0;
1923− }
1924− spaces = 1;
1925− }
1926− else if (IS_BREAK(string))
1927− {
1928− if (!breaks && CHECK(string, '\n')) {
1929− if (!PUT_BREAK(emitter)) return 0;
1930− }
1931− if (!WRITE_BREAK(emitter, string)) return 0;
1932− emitter->indention = 1;
1933− breaks = 1;
1934− }
1935− else
1936− {
1937− if (breaks) {
1938− if (!yaml_emitter_write_indent(emitter)) return 0;
1939− }
1940− if (!WRITE(emitter, string)) return 0;
1941− emitter->indention = 0;
1942− spaces = 0;
1943− breaks = 0;
1944− }
1945− }
1946−
1947− emitter->whitespace = 0;
1948− emitter->indention = 0;
1949−
1950− return 1;
1951−}
1952−
1953−static int
1954−yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter,
1955− yaml_char_t *value, size_t length, int allow_breaks)
1956−{
1957− yaml_string_t string;
1958− int spaces = 0;
1959− int breaks = 0;
1960−
1961− STRING_ASSIGN(string, value, length);
1962−
1963− if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0))
1964− return 0;
1965−
1966− while (string.pointer != string.end)
1967− {
1968− if (IS_SPACE(string))
1969− {
1970− if (allow_breaks && !spaces
1971− && emitter->column > emitter->best_width
1972− && string.pointer != string.start
1973− && string.pointer != string.end - 1
1974− && !IS_SPACE_AT(string, 1)) {
1975− if (!yaml_emitter_write_indent(emitter)) return 0;
1976− MOVE(string);
1977− }
1978− else {
1979− if (!WRITE(emitter, string)) return 0;
1980− }
1981− spaces = 1;
1982− }
1983− else if (IS_BREAK(string))
1984− {
1985− if (!breaks && CHECK(string, '\n')) {
1986− if (!PUT_BREAK(emitter)) return 0;
1987− }
1988− if (!WRITE_BREAK(emitter, string)) return 0;
1989− emitter->indention = 1;
1990− breaks = 1;
1991− }
1992− else
1993− {
1994− if (breaks) {
1995− if (!yaml_emitter_write_indent(emitter)) return 0;
1996− }
1997− if (CHECK(string, '\'')) {
1998− if (!PUT(emitter, '\'')) return 0;
1999− }
2000− if (!WRITE(emitter, string)) return 0;
2001− emitter->indention = 0;
2002− spaces = 0;
2003− breaks = 0;
2004− }
2005− }
2006−
2007− if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0))
2008− return 0;
2009−
2010− emitter->whitespace = 0;
2011− emitter->indention = 0;
2012−
2013− return 1;
2014−}
2015−
2016−static int
2017−yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter,
2018− yaml_char_t *value, size_t length, int allow_breaks)
2019−{
2020− yaml_string_t string;
2021− int spaces = 0;
2022−
2023− STRING_ASSIGN(string, value, length);
2024−
2025− if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0))
2026− return 0;
2027−
2028− while (string.pointer != string.end)
2029− {
2030− if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string))
2031− || IS_BOM(string) || IS_BREAK(string)
2032− || CHECK(string, '"') || CHECK(string, '\\'))
2033− {
2034− unsigned char octet;
2035− unsigned int width;
2036− unsigned int value;
2037− int k;
2038−
2039− octet = string.pointer[0];
2040− width = (octet & 0x80) == 0x00 ? 1 :
2041− (octet & 0xE0) == 0xC0 ? 2 :
2042− (octet & 0xF0) == 0xE0 ? 3 :
2043− (octet & 0xF8) == 0xF0 ? 4 : 0;
2044− value = (octet & 0x80) == 0x00 ? octet & 0x7F :
2045− (octet & 0xE0) == 0xC0 ? octet & 0x1F :
2046− (octet & 0xF0) == 0xE0 ? octet & 0x0F :
2047− (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
2048− for (k = 1; k < (int)width; k ++) {
2049− octet = string.pointer[k];
2050− value = (value << 6) + (octet & 0x3F);
2051− }
2052− string.pointer += width;
2053−
2054− if (!PUT(emitter, '\\')) return 0;
2055−
2056− switch (value)
2057− {
2058− case 0x00:
2059− if (!PUT(emitter, '0')) return 0;
2060− break;
2061−
2062− case 0x07:
2063− if (!PUT(emitter, 'a')) return 0;
2064− break;
2065−
2066− case 0x08:
2067− if (!PUT(emitter, 'b')) return 0;
2068− break;
2069−
2070− case 0x09:
2071− if (!PUT(emitter, 't')) return 0;
2072− break;
2073−
2074− case 0x0A:
2075− if (!PUT(emitter, 'n')) return 0;
2076− break;
2077−
2078− case 0x0B:
2079− if (!PUT(emitter, 'v')) return 0;
2080− break;
2081−
2082− case 0x0C:
2083− if (!PUT(emitter, 'f')) return 0;
2084− break;
2085−
2086− case 0x0D:
2087− if (!PUT(emitter, 'r')) return 0;
2088− break;
2089−
2090− case 0x1B:
2091− if (!PUT(emitter, 'e')) return 0;
2092− break;
2093−
2094− case 0x22:
2095− if (!PUT(emitter, '\"')) return 0;
2096− break;
2097−
2098− case 0x5C:
2099− if (!PUT(emitter, '\\')) return 0;
2100− break;
2101−
2102− case 0x85:
2103− if (!PUT(emitter, 'N')) return 0;
2104− break;
2105−
2106− case 0xA0:
2107− if (!PUT(emitter, '_')) return 0;
2108− break;
2109−
2110− case 0x2028:
2111− if (!PUT(emitter, 'L')) return 0;
2112− break;
2113−
2114− case 0x2029:
2115− if (!PUT(emitter, 'P')) return 0;
2116− break;
2117−
2118− default:
2119− if (value <= 0xFF) {
2120− if (!PUT(emitter, 'x')) return 0;
2121− width = 2;
2122− }
2123− else if (value <= 0xFFFF) {
2124− if (!PUT(emitter, 'u')) return 0;
2125− width = 4;
2126− }
2127− else {
2128− if (!PUT(emitter, 'U')) return 0;
2129− width = 8;
2130− }
2131− for (k = (width-1)*4; k >= 0; k -= 4) {
2132− int digit = (value >> k) & 0x0F;
2133− if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10)))
2134− return 0;
2135− }
2136− }
2137− spaces = 0;
2138− }
2139− else if (IS_SPACE(string))
2140− {
2141− if (allow_breaks && !spaces
2142− && emitter->column > emitter->best_width
2143− && string.pointer != string.start
2144− && string.pointer != string.end - 1) {
2145− if (!yaml_emitter_write_indent(emitter)) return 0;
2146− if (IS_SPACE_AT(string, 1)) {
2147− if (!PUT(emitter, '\\')) return 0;
2148− }
2149− MOVE(string);
2150− }
2151− else {
2152− if (!WRITE(emitter, string)) return 0;
2153− }
2154− spaces = 1;
2155− }
2156− else
2157− {
2158− if (!WRITE(emitter, string)) return 0;
2159− spaces = 0;
2160− }
2161− }
2162−
2163− if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0))
2164− return 0;
2165−
2166− emitter->whitespace = 0;
2167− emitter->indention = 0;
2168−
2169− return 1;
2170−}
2171−
2172−static int
2173−yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter,
2174− yaml_string_t string)
2175−{
2176− char indent_hint[2];
2177− char *chomp_hint = NULL;
2178−
2179− if (IS_SPACE(string) || IS_BREAK(string))
2180− {
2181− indent_hint[0] = '0' + (char)emitter->best_indent;
2182− indent_hint[1] = '\0';
2183− if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0))
2184− return 0;
2185− }
2186−
2187− emitter->open_ended = 0;
2188−
2189− string.pointer = string.end;
2190− if (string.start == string.pointer)
2191− {
2192− chomp_hint = "-";
2193− }
2194− else
2195− {
2196− do {
2197− string.pointer --;
2198− } while ((*string.pointer & 0xC0) == 0x80);
2199− if (!IS_BREAK(string))
2200− {
2201− chomp_hint = "-";
2202− }
2203− else if (string.start == string.pointer)
2204− {
2205− chomp_hint = "+";
2206− emitter->open_ended = 1;
2207− }
2208− else
2209− {
2210− do {
2211− string.pointer --;
2212− } while ((*string.pointer & 0xC0) == 0x80);
2213− if (IS_BREAK(string))
2214− {
2215− chomp_hint = "+";
2216− emitter->open_ended = 1;
2217− }
2218− }
2219− }
2220−
2221− if (chomp_hint)
2222− {
2223− if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0))
2224− return 0;
2225− }
2226−
2227− return 1;
2228−}
2229−
2230−static int
2231−yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter,
2232− yaml_char_t *value, size_t length)
2233−{
2234− yaml_string_t string;
2235− int breaks = 1;
2236−
2237− STRING_ASSIGN(string, value, length);
2238−
2239− if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0))
2240− return 0;
2241− if (!yaml_emitter_write_block_scalar_hints(emitter, string))
2242− return 0;
2243− if (!PUT_BREAK(emitter)) return 0;
2244− emitter->indention = 1;
2245− emitter->whitespace = 1;
2246−
2247− while (string.pointer != string.end)
2248− {
2249− if (IS_BREAK(string))
2250− {
2251− if (!WRITE_BREAK(emitter, string)) return 0;
2252− emitter->indention = 1;
2253− breaks = 1;
2254− }
2255− else
2256− {
2257− if (breaks) {
2258− if (!yaml_emitter_write_indent(emitter)) return 0;
2259− }
2260− if (!WRITE(emitter, string)) return 0;
2261− emitter->indention = 0;
2262− breaks = 0;
2263− }
2264− }
2265−
2266− return 1;
2267−}
2268−
2269−static int
2270−yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter,
2271− yaml_char_t *value, size_t length)
2272−{
2273− yaml_string_t string;
2274− int breaks = 1;
2275− int leading_spaces = 1;
2276−
2277− STRING_ASSIGN(string, value, length);
2278−
2279− if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0))
2280− return 0;
2281− if (!yaml_emitter_write_block_scalar_hints(emitter, string))
2282− return 0;
2283− if (!PUT_BREAK(emitter)) return 0;
2284− emitter->indention = 1;
2285− emitter->whitespace = 1;
2286−
2287− while (string.pointer != string.end)
2288− {
2289− if (IS_BREAK(string))
2290− {
2291− if (!breaks && !leading_spaces && CHECK(string, '\n')) {
2292− int k = 0;
2293− while (IS_BREAK_AT(string, k)) {
2294− k += WIDTH_AT(string, k);
2295− }
2296− if (!IS_BLANKZ_AT(string, k)) {
2297− if (!PUT_BREAK(emitter)) return 0;
2298− }
2299− }
2300− if (!WRITE_BREAK(emitter, string)) return 0;
2301− emitter->indention = 1;
2302− breaks = 1;
2303− }
2304− else
2305− {
2306− if (breaks) {
2307− if (!yaml_emitter_write_indent(emitter)) return 0;
2308− leading_spaces = IS_BLANK(string);
2309− }
2310− if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1)
2311− && emitter->column > emitter->best_width) {
2312− if (!yaml_emitter_write_indent(emitter)) return 0;
2313− MOVE(string);
2314− }
2315− else {
2316− if (!WRITE(emitter, string)) return 0;
2317− }
2318− emitter->indention = 0;
2319− breaks = 0;
2320− }
2321− }
2322−
2323− return 1;
2324−}
c/helper.h → libyaml/include/helper.hrenamed

The content is the same.

libyaml/libyaml.cabalnew file+68
@@ -0,0 +1,68 @@
1+cabal-version: 1.12
2+
3+-- This file has been generated from package.yaml by hpack version 0.36.0.
4+--
5+-- see: https://github.com/sol/hpack
6+
7+name: libyaml
8+version: 0.1.4
9+synopsis: Low-level, streaming YAML interface.
10+description: README and API documentation are available at <https://www.stackage.org/package/libyaml>
11+category: Text
12+stability: stable
13+homepage: https://github.com/snoyberg/yaml#readme
14+bug-reports: https://github.com/snoyberg/yaml/issues
15+author: Michael Snoyman <michael@snoyman.com>, Anton Ageev <antage@gmail.com>,Kirill Simonov
16+maintainer: Michael Snoyman <michael@snoyman.com>
17+license: BSD3
18+license-file: LICENSE
19+build-type: Simple
20+extra-source-files:
21+ include/helper.h
22+ README.md
23+ ChangeLog.md
24+
25+source-repository head
26+ type: git
27+ location: https://github.com/snoyberg/yaml
28+
29+flag no-unicode
30+ description: Don't enable unicode output. Instead, unicode characters will be escaped.
31+ manual: False
32+ default: False
33+
34+flag system-libyaml
35+ description: Use the system-wide libyaml instead of the bundled copy
36+ manual: False
37+ default: False
38+
39+library
40+ exposed-modules:
41+ Text.Libyaml
42+ other-modules:
43+ Paths_libyaml
44+ hs-source-dirs:
45+ src
46+ ghc-options: -Wall
47+ include-dirs:
48+ include
49+ c-sources:
50+ c/helper.c
51+ build-depends:
52+ base >=4.9.1 && <5
53+ , bytestring >=0.9.1.4
54+ , conduit >=1.2.8 && <1.4
55+ , resourcet >=0.3 && <1.4
56+ default-language: Haskell2010
57+ if flag(no-unicode)
58+ cpp-options: -D__NO_UNICODE__
59+ if !(flag(system-libyaml))
60+ build-depends:
61+ libyaml-clib
62+ else
63+ pkgconfig-depends:
64+ yaml-0.1
65+ if os(windows)
66+ cpp-options: -DWINDOWS
67+ build-depends:
68+ directory
libyaml/loader.cdeleted−444
@@ -1,444 +0,0 @@
1−
2−#include "yaml_private.h"
3−
4−/*
5− * API functions.
6− */
7−
8−YAML_DECLARE(int)
9−yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
10−
11−/*
12− * Error handling.
13− */
14−
15−static int
16−yaml_parser_set_composer_error(yaml_parser_t *parser,
17− const char *problem, yaml_mark_t problem_mark);
18−
19−static int
20−yaml_parser_set_composer_error_context(yaml_parser_t *parser,
21− const char *context, yaml_mark_t context_mark,
22− const char *problem, yaml_mark_t problem_mark);
23−
24−
25−/*
26− * Alias handling.
27− */
28−
29−static int
30−yaml_parser_register_anchor(yaml_parser_t *parser,
31− int index, yaml_char_t *anchor);
32−
33−/*
34− * Clean up functions.
35− */
36−
37−static void
38−yaml_parser_delete_aliases(yaml_parser_t *parser);
39−
40−/*
41− * Composer functions.
42− */
43−
44−static int
45−yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
46−
47−static int
48−yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
49−
50−static int
51−yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
52−
53−static int
54−yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
55−
56−static int
57−yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
58−
59−static int
60−yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
61−
62−/*
63− * Load the next document of the stream.
64− */
65−
66−YAML_DECLARE(int)
67−yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
68−{
69− yaml_event_t event;
70−
71− assert(parser); /* Non-NULL parser object is expected. */
72− assert(document); /* Non-NULL document object is expected. */
73−
74− memset(document, 0, sizeof(yaml_document_t));
75− if (!STACK_INIT(parser, document->nodes, yaml_node_t*))
76− goto error;
77−
78− if (!parser->stream_start_produced) {
79− if (!yaml_parser_parse(parser, &event)) goto error;
80− assert(event.type == YAML_STREAM_START_EVENT);
81− /* STREAM-START is expected. */
82− }
83−
84− if (parser->stream_end_produced) {
85− return 1;
86− }
87−
88− if (!yaml_parser_parse(parser, &event)) goto error;
89− if (event.type == YAML_STREAM_END_EVENT) {
90− return 1;
91− }
92−
93− if (!STACK_INIT(parser, parser->aliases, yaml_alias_data_t*))
94− goto error;
95−
96− parser->document = document;
97−
98− if (!yaml_parser_load_document(parser, &event)) goto error;
99−
100− yaml_parser_delete_aliases(parser);
101− parser->document = NULL;
102−
103− return 1;
104−
105−error:
106−
107− yaml_parser_delete_aliases(parser);
108− yaml_document_delete(document);
109− parser->document = NULL;
110−
111− return 0;
112−}
113−
114−/*
115− * Set composer error.
116− */
117−
118−static int
119−yaml_parser_set_composer_error(yaml_parser_t *parser,
120− const char *problem, yaml_mark_t problem_mark)
121−{
122− parser->error = YAML_COMPOSER_ERROR;
123− parser->problem = problem;
124− parser->problem_mark = problem_mark;
125−
126− return 0;
127−}
128−
129−/*
130− * Set composer error with context.
131− */
132−
133−static int
134−yaml_parser_set_composer_error_context(yaml_parser_t *parser,
135− const char *context, yaml_mark_t context_mark,
136− const char *problem, yaml_mark_t problem_mark)
137−{
138− parser->error = YAML_COMPOSER_ERROR;
139− parser->context = context;
140− parser->context_mark = context_mark;
141− parser->problem = problem;
142− parser->problem_mark = problem_mark;
143−
144− return 0;
145−}
146−
147−/*
148− * Delete the stack of aliases.
149− */
150−
151−static void
152−yaml_parser_delete_aliases(yaml_parser_t *parser)
153−{
154− while (!STACK_EMPTY(parser, parser->aliases)) {
155− yaml_free(POP(parser, parser->aliases).anchor);
156− }
157− STACK_DEL(parser, parser->aliases);
158−}
159−
160−/*
161− * Compose a document object.
162− */
163−
164−static int
165−yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
166−{
167− yaml_event_t event;
168−
169− assert(first_event->type == YAML_DOCUMENT_START_EVENT);
170− /* DOCUMENT-START is expected. */
171−
172− parser->document->version_directive
173− = first_event->data.document_start.version_directive;
174− parser->document->tag_directives.start
175− = first_event->data.document_start.tag_directives.start;
176− parser->document->tag_directives.end
177− = first_event->data.document_start.tag_directives.end;
178− parser->document->start_implicit
179− = first_event->data.document_start.implicit;
180− parser->document->start_mark = first_event->start_mark;
181−
182− if (!yaml_parser_parse(parser, &event)) return 0;
183−
184− if (!yaml_parser_load_node(parser, &event)) return 0;
185−
186− if (!yaml_parser_parse(parser, &event)) return 0;
187− assert(event.type == YAML_DOCUMENT_END_EVENT);
188− /* DOCUMENT-END is expected. */
189−
190− parser->document->end_implicit = event.data.document_end.implicit;
191− parser->document->end_mark = event.end_mark;
192−
193− return 1;
194−}
195−
196−/*
197− * Compose a node.
198− */
199−
200−static int
201−yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
202−{
203− switch (first_event->type) {
204− case YAML_ALIAS_EVENT:
205− return yaml_parser_load_alias(parser, first_event);
206− case YAML_SCALAR_EVENT:
207− return yaml_parser_load_scalar(parser, first_event);
208− case YAML_SEQUENCE_START_EVENT:
209− return yaml_parser_load_sequence(parser, first_event);
210− case YAML_MAPPING_START_EVENT:
211− return yaml_parser_load_mapping(parser, first_event);
212− default:
213− assert(0); /* Could not happen. */
214− return 0;
215− }
216−
217− return 0;
218−}
219−
220−/*
221− * Add an anchor.
222− */
223−
224−static int
225−yaml_parser_register_anchor(yaml_parser_t *parser,
226− int index, yaml_char_t *anchor)
227−{
228− yaml_alias_data_t data;
229− yaml_alias_data_t *alias_data;
230−
231− if (!anchor) return 1;
232−
233− data.anchor = anchor;
234− data.index = index;
235− data.mark = parser->document->nodes.start[index-1].start_mark;
236−
237− for (alias_data = parser->aliases.start;
238− alias_data != parser->aliases.top; alias_data ++) {
239− if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
240− yaml_free(anchor);
241− return yaml_parser_set_composer_error_context(parser,
242− "found duplicate anchor; first occurrence",
243− alias_data->mark, "second occurrence", data.mark);
244− }
245− }
246−
247− if (!PUSH(parser, parser->aliases, data)) {
248− yaml_free(anchor);
249− return 0;
250− }
251−
252− return 1;
253−}
254−
255−/*
256− * Compose a node corresponding to an alias.
257− */
258−
259−static int
260−yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
261−{
262− yaml_char_t *anchor = first_event->data.alias.anchor;
263− yaml_alias_data_t *alias_data;
264−
265− for (alias_data = parser->aliases.start;
266− alias_data != parser->aliases.top; alias_data ++) {
267− if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
268− yaml_free(anchor);
269− return alias_data->index;
270− }
271− }
272−
273− yaml_free(anchor);
274− return yaml_parser_set_composer_error(parser, "found undefined alias",
275− first_event->start_mark);
276−}
277−
278−/*
279− * Compose a scalar node.
280− */
281−
282−static int
283−yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
284−{
285− yaml_node_t node;
286− int index;
287− yaml_char_t *tag = first_event->data.scalar.tag;
288−
289− if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
290−
291− if (!tag || strcmp((char *)tag, "!") == 0) {
292− yaml_free(tag);
293− tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
294− if (!tag) goto error;
295− }
296−
297− SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
298− first_event->data.scalar.length, first_event->data.scalar.style,
299− first_event->start_mark, first_event->end_mark);
300−
301− if (!PUSH(parser, parser->document->nodes, node)) goto error;
302−
303− index = parser->document->nodes.top - parser->document->nodes.start;
304−
305− if (!yaml_parser_register_anchor(parser, index,
306− first_event->data.scalar.anchor)) return 0;
307−
308− return index;
309−
310−error:
311− yaml_free(tag);
312− yaml_free(first_event->data.scalar.anchor);
313− yaml_free(first_event->data.scalar.value);
314− return 0;
315−}
316−
317−/*
318− * Compose a sequence node.
319− */
320−
321−static int
322−yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
323−{
324− yaml_event_t event;
325− yaml_node_t node;
326− struct {
327− yaml_node_item_t *start;
328− yaml_node_item_t *end;
329− yaml_node_item_t *top;
330− } items = { NULL, NULL, NULL };
331− int index, item_index;
332− yaml_char_t *tag = first_event->data.sequence_start.tag;
333−
334− if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
335−
336− if (!tag || strcmp((char *)tag, "!") == 0) {
337− yaml_free(tag);
338− tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
339− if (!tag) goto error;
340− }
341−
342− if (!STACK_INIT(parser, items, yaml_node_item_t*)) goto error;
343−
344− SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
345− first_event->data.sequence_start.style,
346− first_event->start_mark, first_event->end_mark);
347−
348− if (!PUSH(parser, parser->document->nodes, node)) goto error;
349−
350− index = parser->document->nodes.top - parser->document->nodes.start;
351−
352− if (!yaml_parser_register_anchor(parser, index,
353− first_event->data.sequence_start.anchor)) return 0;
354−
355− if (!yaml_parser_parse(parser, &event)) return 0;
356−
357− while (event.type != YAML_SEQUENCE_END_EVENT) {
358− if (!STACK_LIMIT(parser,
359− parser->document->nodes.start[index-1].data.sequence.items,
360− INT_MAX-1)) return 0;
361− item_index = yaml_parser_load_node(parser, &event);
362− if (!item_index) return 0;
363− if (!PUSH(parser,
364− parser->document->nodes.start[index-1].data.sequence.items,
365− item_index)) return 0;
366− if (!yaml_parser_parse(parser, &event)) return 0;
367− }
368−
369− parser->document->nodes.start[index-1].end_mark = event.end_mark;
370−
371− return index;
372−
373−error:
374− yaml_free(tag);
375− yaml_free(first_event->data.sequence_start.anchor);
376− return 0;
377−}
378−
379−/*
380− * Compose a mapping node.
381− */
382−
383−static int
384−yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
385−{
386− yaml_event_t event;
387− yaml_node_t node;
388− struct {
389− yaml_node_pair_t *start;
390− yaml_node_pair_t *end;
391− yaml_node_pair_t *top;
392− } pairs = { NULL, NULL, NULL };
393− int index;
394− yaml_node_pair_t pair;
395− yaml_char_t *tag = first_event->data.mapping_start.tag;
396−
397− if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
398−
399− if (!tag || strcmp((char *)tag, "!") == 0) {
400− yaml_free(tag);
401− tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
402− if (!tag) goto error;
403− }
404−
405− if (!STACK_INIT(parser, pairs, yaml_node_pair_t*)) goto error;
406−
407− MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
408− first_event->data.mapping_start.style,
409− first_event->start_mark, first_event->end_mark);
410−
411− if (!PUSH(parser, parser->document->nodes, node)) goto error;
412−
413− index = parser->document->nodes.top - parser->document->nodes.start;
414−
415− if (!yaml_parser_register_anchor(parser, index,
416− first_event->data.mapping_start.anchor)) return 0;
417−
418− if (!yaml_parser_parse(parser, &event)) return 0;
419−
420− while (event.type != YAML_MAPPING_END_EVENT) {
421− if (!STACK_LIMIT(parser,
422− parser->document->nodes.start[index-1].data.mapping.pairs,
423− INT_MAX-1)) return 0;
424− pair.key = yaml_parser_load_node(parser, &event);
425− if (!pair.key) return 0;
426− if (!yaml_parser_parse(parser, &event)) return 0;
427− pair.value = yaml_parser_load_node(parser, &event);
428− if (!pair.value) return 0;
429− if (!PUSH(parser,
430− parser->document->nodes.start[index-1].data.mapping.pairs,
431− pair)) return 0;
432− if (!yaml_parser_parse(parser, &event)) return 0;
433− }
434−
435− parser->document->nodes.start[index-1].end_mark = event.end_mark;
436−
437− return index;
438−
439−error:
440− yaml_free(tag);
441− yaml_free(first_event->data.mapping_start.anchor);
442− return 0;
443−}
444−
libyaml/package.yamlnew file+53
@@ -0,0 +1,53 @@
1+name: libyaml
2+version: 0.1.4
3+synopsis: Low-level, streaming YAML interface.
4+description: README and API documentation are available at <https://www.stackage.org/package/libyaml>
5+category: Text
6+author: Michael Snoyman <michael@snoyman.com>, Anton Ageev <antage@gmail.com>,Kirill Simonov
7+maintainer: Michael Snoyman <michael@snoyman.com>
8+license: BSD3
9+github: snoyberg/yaml
10+stability: stable
11+
12+extra-source-files:
13+- include/helper.h
14+- README.md
15+- ChangeLog.md
16+
17+flags:
18+ system-libyaml:
19+ description: Use the system-wide libyaml instead of the bundled copy
20+ manual: false
21+ default: false
22+ no-unicode:
23+ description: Don't enable unicode output. Instead, unicode characters will be escaped.
24+ manual: false
25+ default: false
26+
27+dependencies:
28+- base >=4.14 && <5 # GHC 8.10.1 and later
29+- bytestring >=0.9.1.4
30+- conduit >=1.2.8 && <1.4
31+- resourcet >=0.3 && <1.4
32+
33+library:
34+ c-sources: c/helper.c
35+ ghc-options: -Wall
36+ include-dirs:
37+ - include
38+ source-dirs: src
39+ when:
40+ - condition: flag(no-unicode)
41+ cpp-options: -D__NO_UNICODE__
42+ - condition: ! '!(flag(system-libyaml))'
43+ then:
44+ dependencies:
45+ - libyaml-clib
46+ else:
47+ pkg-config-dependencies:
48+ - yaml-0.1
49+ - condition: os(windows)
50+ cpp-options: -DWINDOWS
51+ dependencies:
52+ - directory
53+
libyaml/parser.cdeleted−1370
@@ -1,1370 +0,0 @@
1−
2−/*
3− * The parser implements the following grammar:
4− *
5− * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
6− * implicit_document ::= block_node DOCUMENT-END*
7− * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
8− * block_node_or_indentless_sequence ::=
9− * ALIAS
10− * | properties (block_content | indentless_block_sequence)?
11− * | block_content
12− * | indentless_block_sequence
13− * block_node ::= ALIAS
14− * | properties block_content?
15− * | block_content
16− * flow_node ::= ALIAS
17− * | properties flow_content?
18− * | flow_content
19− * properties ::= TAG ANCHOR? | ANCHOR TAG?
20− * block_content ::= block_collection | flow_collection | SCALAR
21− * flow_content ::= flow_collection | SCALAR
22− * block_collection ::= block_sequence | block_mapping
23− * flow_collection ::= flow_sequence | flow_mapping
24− * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
25− * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
26− * block_mapping ::= BLOCK-MAPPING_START
27− * ((KEY block_node_or_indentless_sequence?)?
28− * (VALUE block_node_or_indentless_sequence?)?)*
29− * BLOCK-END
30− * flow_sequence ::= FLOW-SEQUENCE-START
31− * (flow_sequence_entry FLOW-ENTRY)*
32− * flow_sequence_entry?
33− * FLOW-SEQUENCE-END
34− * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
35− * flow_mapping ::= FLOW-MAPPING-START
36− * (flow_mapping_entry FLOW-ENTRY)*
37− * flow_mapping_entry?
38− * FLOW-MAPPING-END
39− * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
40− */
41−
42−#include "yaml_private.h"
43−
44−/*
45− * Peek the next token in the token queue.
46− */
47−
48−#define PEEK_TOKEN(parser) \
49− ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \
50− parser->tokens.head : NULL)
51−
52−/*
53− * Remove the next token from the queue (must be called after PEEK_TOKEN).
54− */
55−
56−#define SKIP_TOKEN(parser) \
57− (parser->token_available = 0, \
58− parser->tokens_parsed ++, \
59− parser->stream_end_produced = \
60− (parser->tokens.head->type == YAML_STREAM_END_TOKEN), \
61− parser->tokens.head ++)
62−
63−/*
64− * Public API declarations.
65− */
66−
67−YAML_DECLARE(int)
68−yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
69−
70−/*
71− * Error handling.
72− */
73−
74−static int
75−yaml_parser_set_parser_error(yaml_parser_t *parser,
76− const char *problem, yaml_mark_t problem_mark);
77−
78−static int
79−yaml_parser_set_parser_error_context(yaml_parser_t *parser,
80− const char *context, yaml_mark_t context_mark,
81− const char *problem, yaml_mark_t problem_mark);
82−
83−/*
84− * State functions.
85− */
86−
87−static int
88−yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event);
89−
90−static int
91−yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event);
92−
93−static int
94−yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
95− int implicit);
96−
97−static int
98−yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event);
99−
100−static int
101−yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event);
102−
103−static int
104−yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
105− int block, int indentless_sequence);
106−
107−static int
108−yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
109− yaml_event_t *event, int first);
110−
111−static int
112−yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
113− yaml_event_t *event);
114−
115−static int
116−yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
117− yaml_event_t *event, int first);
118−
119−static int
120−yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
121− yaml_event_t *event);
122−
123−static int
124−yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
125− yaml_event_t *event, int first);
126−
127−static int
128−yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
129− yaml_event_t *event);
130−
131−static int
132−yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
133− yaml_event_t *event);
134−
135−static int
136−yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
137− yaml_event_t *event);
138−
139−static int
140−yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
141− yaml_event_t *event, int first);
142−
143−static int
144−yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
145− yaml_event_t *event, int empty);
146−
147−/*
148− * Utility functions.
149− */
150−
151−static int
152−yaml_parser_process_empty_scalar(yaml_parser_t *parser,
153− yaml_event_t *event, yaml_mark_t mark);
154−
155−static int
156−yaml_parser_process_directives(yaml_parser_t *parser,
157− yaml_version_directive_t **version_directive_ref,
158− yaml_tag_directive_t **tag_directives_start_ref,
159− yaml_tag_directive_t **tag_directives_end_ref);
160−
161−static int
162−yaml_parser_append_tag_directive(yaml_parser_t *parser,
163− yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark);
164−
165−/*
166− * Get the next event.
167− */
168−
169−YAML_DECLARE(int)
170−yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event)
171−{
172− assert(parser); /* Non-NULL parser object is expected. */
173− assert(event); /* Non-NULL event object is expected. */
174−
175− /* Erase the event object. */
176−
177− memset(event, 0, sizeof(yaml_event_t));
178−
179− /* No events after the end of the stream or error. */
180−
181− if (parser->stream_end_produced || parser->error ||
182− parser->state == YAML_PARSE_END_STATE) {
183− return 1;
184− }
185−
186− /* Generate the next event. */
187−
188− return yaml_parser_state_machine(parser, event);
189−}
190−
191−/*
192− * Set parser error.
193− */
194−
195−static int
196−yaml_parser_set_parser_error(yaml_parser_t *parser,
197− const char *problem, yaml_mark_t problem_mark)
198−{
199− parser->error = YAML_PARSER_ERROR;
200− parser->problem = problem;
201− parser->problem_mark = problem_mark;
202−
203− return 0;
204−}
205−
206−static int
207−yaml_parser_set_parser_error_context(yaml_parser_t *parser,
208− const char *context, yaml_mark_t context_mark,
209− const char *problem, yaml_mark_t problem_mark)
210−{
211− parser->error = YAML_PARSER_ERROR;
212− parser->context = context;
213− parser->context_mark = context_mark;
214− parser->problem = problem;
215− parser->problem_mark = problem_mark;
216−
217− return 0;
218−}
219−
220−
221−/*
222− * State dispatcher.
223− */
224−
225−static int
226−yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event)
227−{
228− switch (parser->state)
229− {
230− case YAML_PARSE_STREAM_START_STATE:
231− return yaml_parser_parse_stream_start(parser, event);
232−
233− case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE:
234− return yaml_parser_parse_document_start(parser, event, 1);
235−
236− case YAML_PARSE_DOCUMENT_START_STATE:
237− return yaml_parser_parse_document_start(parser, event, 0);
238−
239− case YAML_PARSE_DOCUMENT_CONTENT_STATE:
240− return yaml_parser_parse_document_content(parser, event);
241−
242− case YAML_PARSE_DOCUMENT_END_STATE:
243− return yaml_parser_parse_document_end(parser, event);
244−
245− case YAML_PARSE_BLOCK_NODE_STATE:
246− return yaml_parser_parse_node(parser, event, 1, 0);
247−
248− case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:
249− return yaml_parser_parse_node(parser, event, 1, 1);
250−
251− case YAML_PARSE_FLOW_NODE_STATE:
252− return yaml_parser_parse_node(parser, event, 0, 0);
253−
254− case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:
255− return yaml_parser_parse_block_sequence_entry(parser, event, 1);
256−
257− case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:
258− return yaml_parser_parse_block_sequence_entry(parser, event, 0);
259−
260− case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:
261− return yaml_parser_parse_indentless_sequence_entry(parser, event);
262−
263− case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:
264− return yaml_parser_parse_block_mapping_key(parser, event, 1);
265−
266− case YAML_PARSE_BLOCK_MAPPING_KEY_STATE:
267− return yaml_parser_parse_block_mapping_key(parser, event, 0);
268−
269− case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE:
270− return yaml_parser_parse_block_mapping_value(parser, event);
271−
272− case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:
273− return yaml_parser_parse_flow_sequence_entry(parser, event, 1);
274−
275− case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE:
276− return yaml_parser_parse_flow_sequence_entry(parser, event, 0);
277−
278− case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:
279− return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event);
280−
281− case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:
282− return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event);
283−
284− case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:
285− return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event);
286−
287− case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:
288− return yaml_parser_parse_flow_mapping_key(parser, event, 1);
289−
290− case YAML_PARSE_FLOW_MAPPING_KEY_STATE:
291− return yaml_parser_parse_flow_mapping_key(parser, event, 0);
292−
293− case YAML_PARSE_FLOW_MAPPING_VALUE_STATE:
294− return yaml_parser_parse_flow_mapping_value(parser, event, 0);
295−
296− case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:
297− return yaml_parser_parse_flow_mapping_value(parser, event, 1);
298−
299− default:
300− assert(1); /* Invalid state. */
301− }
302−
303− return 0;
304−}
305−
306−/*
307− * Parse the production:
308− * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END
309− * ************
310− */
311−
312−static int
313−yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event)
314−{
315− yaml_token_t *token;
316−
317− token = PEEK_TOKEN(parser);
318− if (!token) return 0;
319−
320− if (token->type != YAML_STREAM_START_TOKEN) {
321− return yaml_parser_set_parser_error(parser,
322− "did not find expected <stream-start>", token->start_mark);
323− }
324−
325− parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
326− STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding,
327− token->start_mark, token->start_mark);
328− SKIP_TOKEN(parser);
329−
330− return 1;
331−}
332−
333−/*
334− * Parse the productions:
335− * implicit_document ::= block_node DOCUMENT-END*
336− * *
337− * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
338− * *************************
339− */
340−
341−static int
342−yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event,
343− int implicit)
344−{
345− yaml_token_t *token;
346− yaml_version_directive_t *version_directive = NULL;
347− struct {
348− yaml_tag_directive_t *start;
349− yaml_tag_directive_t *end;
350− } tag_directives = { NULL, NULL };
351−
352− token = PEEK_TOKEN(parser);
353− if (!token) return 0;
354−
355− /* Parse extra document end indicators. */
356−
357− if (!implicit)
358− {
359− while (token->type == YAML_DOCUMENT_END_TOKEN) {
360− SKIP_TOKEN(parser);
361− token = PEEK_TOKEN(parser);
362− if (!token) return 0;
363− }
364− }
365−
366− /* Parse an implicit document. */
367−
368− if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN &&
369− token->type != YAML_TAG_DIRECTIVE_TOKEN &&
370− token->type != YAML_DOCUMENT_START_TOKEN &&
371− token->type != YAML_STREAM_END_TOKEN)
372− {
373− if (!yaml_parser_process_directives(parser, NULL, NULL, NULL))
374− return 0;
375− if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
376− return 0;
377− parser->state = YAML_PARSE_BLOCK_NODE_STATE;
378− DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1,
379− token->start_mark, token->start_mark);
380− return 1;
381− }
382−
383− /* Parse an explicit document. */
384−
385− else if (token->type != YAML_STREAM_END_TOKEN)
386− {
387− yaml_mark_t start_mark, end_mark;
388− start_mark = token->start_mark;
389− if (!yaml_parser_process_directives(parser, &version_directive,
390− &tag_directives.start, &tag_directives.end))
391− return 0;
392− token = PEEK_TOKEN(parser);
393− if (!token) goto error;
394− if (token->type != YAML_DOCUMENT_START_TOKEN) {
395− yaml_parser_set_parser_error(parser,
396− "did not find expected <document start>", token->start_mark);
397− goto error;
398− }
399− if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE))
400− goto error;
401− parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
402− end_mark = token->end_mark;
403− DOCUMENT_START_EVENT_INIT(*event, version_directive,
404− tag_directives.start, tag_directives.end, 0,
405− start_mark, end_mark);
406− SKIP_TOKEN(parser);
407− version_directive = NULL;
408− tag_directives.start = tag_directives.end = NULL;
409− return 1;
410− }
411−
412− /* Parse the stream end. */
413−
414− else
415− {
416− parser->state = YAML_PARSE_END_STATE;
417− STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
418− SKIP_TOKEN(parser);
419− return 1;
420− }
421−
422−error:
423− yaml_free(version_directive);
424− while (tag_directives.start != tag_directives.end) {
425− yaml_free(tag_directives.end[-1].handle);
426− yaml_free(tag_directives.end[-1].prefix);
427− tag_directives.end --;
428− }
429− yaml_free(tag_directives.start);
430− return 0;
431−}
432−
433−/*
434− * Parse the productions:
435− * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
436− * ***********
437− */
438−
439−static int
440−yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event)
441−{
442− yaml_token_t *token;
443−
444− token = PEEK_TOKEN(parser);
445− if (!token) return 0;
446−
447− if (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
448− token->type == YAML_TAG_DIRECTIVE_TOKEN ||
449− token->type == YAML_DOCUMENT_START_TOKEN ||
450− token->type == YAML_DOCUMENT_END_TOKEN ||
451− token->type == YAML_STREAM_END_TOKEN) {
452− parser->state = POP(parser, parser->states);
453− return yaml_parser_process_empty_scalar(parser, event,
454− token->start_mark);
455− }
456− else {
457− return yaml_parser_parse_node(parser, event, 1, 0);
458− }
459−}
460−
461−/*
462− * Parse the productions:
463− * implicit_document ::= block_node DOCUMENT-END*
464− * *************
465− * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*
466− * *************
467− */
468−
469−static int
470−yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event)
471−{
472− yaml_token_t *token;
473− yaml_mark_t start_mark, end_mark;
474− int implicit = 1;
475−
476− token = PEEK_TOKEN(parser);
477− if (!token) return 0;
478−
479− start_mark = end_mark = token->start_mark;
480−
481− if (token->type == YAML_DOCUMENT_END_TOKEN) {
482− end_mark = token->end_mark;
483− SKIP_TOKEN(parser);
484− implicit = 0;
485− }
486−
487− while (!STACK_EMPTY(parser, parser->tag_directives)) {
488− yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives);
489− yaml_free(tag_directive.handle);
490− yaml_free(tag_directive.prefix);
491− }
492−
493− parser->state = YAML_PARSE_DOCUMENT_START_STATE;
494− DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark);
495−
496− return 1;
497−}
498−
499−/*
500− * Parse the productions:
501− * block_node_or_indentless_sequence ::=
502− * ALIAS
503− * *****
504− * | properties (block_content | indentless_block_sequence)?
505− * ********** *
506− * | block_content | indentless_block_sequence
507− * *
508− * block_node ::= ALIAS
509− * *****
510− * | properties block_content?
511− * ********** *
512− * | block_content
513− * *
514− * flow_node ::= ALIAS
515− * *****
516− * | properties flow_content?
517− * ********** *
518− * | flow_content
519− * *
520− * properties ::= TAG ANCHOR? | ANCHOR TAG?
521− * *************************
522− * block_content ::= block_collection | flow_collection | SCALAR
523− * ******
524− * flow_content ::= flow_collection | SCALAR
525− * ******
526− */
527−
528−static int
529−yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event,
530− int block, int indentless_sequence)
531−{
532− yaml_token_t *token;
533− yaml_char_t *anchor = NULL;
534− yaml_char_t *tag_handle = NULL;
535− yaml_char_t *tag_suffix = NULL;
536− yaml_char_t *tag = NULL;
537− yaml_mark_t start_mark, end_mark, tag_mark;
538− int implicit;
539−
540− token = PEEK_TOKEN(parser);
541− if (!token) return 0;
542−
543− if (token->type == YAML_ALIAS_TOKEN)
544− {
545− parser->state = POP(parser, parser->states);
546− ALIAS_EVENT_INIT(*event, token->data.alias.value,
547− token->start_mark, token->end_mark);
548− SKIP_TOKEN(parser);
549− return 1;
550− }
551−
552− else
553− {
554− start_mark = end_mark = token->start_mark;
555−
556− if (token->type == YAML_ANCHOR_TOKEN)
557− {
558− anchor = token->data.anchor.value;
559− start_mark = token->start_mark;
560− end_mark = token->end_mark;
561− SKIP_TOKEN(parser);
562− token = PEEK_TOKEN(parser);
563− if (!token) goto error;
564− if (token->type == YAML_TAG_TOKEN)
565− {
566− tag_handle = token->data.tag.handle;
567− tag_suffix = token->data.tag.suffix;
568− tag_mark = token->start_mark;
569− end_mark = token->end_mark;
570− SKIP_TOKEN(parser);
571− token = PEEK_TOKEN(parser);
572− if (!token) goto error;
573− }
574− }
575− else if (token->type == YAML_TAG_TOKEN)
576− {
577− tag_handle = token->data.tag.handle;
578− tag_suffix = token->data.tag.suffix;
579− start_mark = tag_mark = token->start_mark;
580− end_mark = token->end_mark;
581− SKIP_TOKEN(parser);
582− token = PEEK_TOKEN(parser);
583− if (!token) goto error;
584− if (token->type == YAML_ANCHOR_TOKEN)
585− {
586− anchor = token->data.anchor.value;
587− end_mark = token->end_mark;
588− SKIP_TOKEN(parser);
589− token = PEEK_TOKEN(parser);
590− if (!token) goto error;
591− }
592− }
593−
594− if (tag_handle) {
595− if (!*tag_handle) {
596− tag = tag_suffix;
597− yaml_free(tag_handle);
598− tag_handle = tag_suffix = NULL;
599− }
600− else {
601− yaml_tag_directive_t *tag_directive;
602− for (tag_directive = parser->tag_directives.start;
603− tag_directive != parser->tag_directives.top;
604− tag_directive ++) {
605− if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) {
606− size_t prefix_len = strlen((char *)tag_directive->prefix);
607− size_t suffix_len = strlen((char *)tag_suffix);
608− tag = YAML_MALLOC(prefix_len+suffix_len+1);
609− if (!tag) {
610− parser->error = YAML_MEMORY_ERROR;
611− goto error;
612− }
613− memcpy(tag, tag_directive->prefix, prefix_len);
614− memcpy(tag+prefix_len, tag_suffix, suffix_len);
615− tag[prefix_len+suffix_len] = '\0';
616− yaml_free(tag_handle);
617− yaml_free(tag_suffix);
618− tag_handle = tag_suffix = NULL;
619− break;
620− }
621− }
622− if (!tag) {
623− yaml_parser_set_parser_error_context(parser,
624− "while parsing a node", start_mark,
625− "found undefined tag handle", tag_mark);
626− goto error;
627− }
628− }
629− }
630−
631− implicit = (!tag || !*tag);
632− if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) {
633− end_mark = token->end_mark;
634− parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
635− SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
636− YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
637− return 1;
638− }
639− else {
640− if (token->type == YAML_SCALAR_TOKEN) {
641− int plain_implicit = 0;
642− int quoted_implicit = 0;
643− end_mark = token->end_mark;
644− if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag)
645− || (tag && strcmp((char *)tag, "!") == 0)) {
646− plain_implicit = 1;
647− }
648− else if (!tag) {
649− quoted_implicit = 1;
650− }
651− parser->state = POP(parser, parser->states);
652− SCALAR_EVENT_INIT(*event, anchor, tag,
653− token->data.scalar.value, token->data.scalar.length,
654− plain_implicit, quoted_implicit,
655− token->data.scalar.style, start_mark, end_mark);
656− SKIP_TOKEN(parser);
657− return 1;
658− }
659− else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) {
660− end_mark = token->end_mark;
661− parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
662− SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
663− YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark);
664− return 1;
665− }
666− else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) {
667− end_mark = token->end_mark;
668− parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
669− MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
670− YAML_FLOW_MAPPING_STYLE, start_mark, end_mark);
671− return 1;
672− }
673− else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) {
674− end_mark = token->end_mark;
675− parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
676− SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit,
677− YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark);
678− return 1;
679− }
680− else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) {
681− end_mark = token->end_mark;
682− parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
683− MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit,
684− YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark);
685− return 1;
686− }
687− else if (anchor || tag) {
688− yaml_char_t *value = YAML_MALLOC(1);
689− if (!value) {
690− parser->error = YAML_MEMORY_ERROR;
691− goto error;
692− }
693− value[0] = '\0';
694− parser->state = POP(parser, parser->states);
695− SCALAR_EVENT_INIT(*event, anchor, tag, value, 0,
696− implicit, 0, YAML_PLAIN_SCALAR_STYLE,
697− start_mark, end_mark);
698− return 1;
699− }
700− else {
701− yaml_parser_set_parser_error_context(parser,
702− (block ? "while parsing a block node"
703− : "while parsing a flow node"), start_mark,
704− "did not find expected node content", token->start_mark);
705− goto error;
706− }
707− }
708− }
709−
710−error:
711− yaml_free(anchor);
712− yaml_free(tag_handle);
713− yaml_free(tag_suffix);
714− yaml_free(tag);
715−
716− return 0;
717−}
718−
719−/*
720− * Parse the productions:
721− * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
722− * ******************** *********** * *********
723− */
724−
725−static int
726−yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser,
727− yaml_event_t *event, int first)
728−{
729− yaml_token_t *token;
730−
731− if (first) {
732− token = PEEK_TOKEN(parser);
733− if (!PUSH(parser, parser->marks, token->start_mark))
734− return 0;
735− SKIP_TOKEN(parser);
736− }
737−
738− token = PEEK_TOKEN(parser);
739− if (!token) return 0;
740−
741− if (token->type == YAML_BLOCK_ENTRY_TOKEN)
742− {
743− yaml_mark_t mark = token->end_mark;
744− SKIP_TOKEN(parser);
745− token = PEEK_TOKEN(parser);
746− if (!token) return 0;
747− if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
748− token->type != YAML_BLOCK_END_TOKEN) {
749− if (!PUSH(parser, parser->states,
750− YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE))
751− return 0;
752− return yaml_parser_parse_node(parser, event, 1, 0);
753− }
754− else {
755− parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
756− return yaml_parser_process_empty_scalar(parser, event, mark);
757− }
758− }
759−
760− else if (token->type == YAML_BLOCK_END_TOKEN)
761− {
762− parser->state = POP(parser, parser->states);
763− (void)POP(parser, parser->marks);
764− SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
765− SKIP_TOKEN(parser);
766− return 1;
767− }
768−
769− else
770− {
771− return yaml_parser_set_parser_error_context(parser,
772− "while parsing a block collection", POP(parser, parser->marks),
773− "did not find expected '-' indicator", token->start_mark);
774− }
775−}
776−
777−/*
778− * Parse the productions:
779− * indentless_sequence ::= (BLOCK-ENTRY block_node?)+
780− * *********** *
781− */
782−
783−static int
784−yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser,
785− yaml_event_t *event)
786−{
787− yaml_token_t *token;
788−
789− token = PEEK_TOKEN(parser);
790− if (!token) return 0;
791−
792− if (token->type == YAML_BLOCK_ENTRY_TOKEN)
793− {
794− yaml_mark_t mark = token->end_mark;
795− SKIP_TOKEN(parser);
796− token = PEEK_TOKEN(parser);
797− if (!token) return 0;
798− if (token->type != YAML_BLOCK_ENTRY_TOKEN &&
799− token->type != YAML_KEY_TOKEN &&
800− token->type != YAML_VALUE_TOKEN &&
801− token->type != YAML_BLOCK_END_TOKEN) {
802− if (!PUSH(parser, parser->states,
803− YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE))
804− return 0;
805− return yaml_parser_parse_node(parser, event, 1, 0);
806− }
807− else {
808− parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
809− return yaml_parser_process_empty_scalar(parser, event, mark);
810− }
811− }
812−
813− else
814− {
815− parser->state = POP(parser, parser->states);
816− SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
817− return 1;
818− }
819−}
820−
821−/*
822− * Parse the productions:
823− * block_mapping ::= BLOCK-MAPPING_START
824− * *******************
825− * ((KEY block_node_or_indentless_sequence?)?
826− * *** *
827− * (VALUE block_node_or_indentless_sequence?)?)*
828− *
829− * BLOCK-END
830− * *********
831− */
832−
833−static int
834−yaml_parser_parse_block_mapping_key(yaml_parser_t *parser,
835− yaml_event_t *event, int first)
836−{
837− yaml_token_t *token;
838−
839− if (first) {
840− token = PEEK_TOKEN(parser);
841− if (!PUSH(parser, parser->marks, token->start_mark))
842− return 0;
843− SKIP_TOKEN(parser);
844− }
845−
846− token = PEEK_TOKEN(parser);
847− if (!token) return 0;
848−
849− if (token->type == YAML_KEY_TOKEN)
850− {
851− yaml_mark_t mark = token->end_mark;
852− SKIP_TOKEN(parser);
853− token = PEEK_TOKEN(parser);
854− if (!token) return 0;
855− if (token->type != YAML_KEY_TOKEN &&
856− token->type != YAML_VALUE_TOKEN &&
857− token->type != YAML_BLOCK_END_TOKEN) {
858− if (!PUSH(parser, parser->states,
859− YAML_PARSE_BLOCK_MAPPING_VALUE_STATE))
860− return 0;
861− return yaml_parser_parse_node(parser, event, 1, 1);
862− }
863− else {
864− parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
865− return yaml_parser_process_empty_scalar(parser, event, mark);
866− }
867− }
868−
869− else if (token->type == YAML_BLOCK_END_TOKEN)
870− {
871− parser->state = POP(parser, parser->states);
872− (void)POP(parser, parser->marks);
873− MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
874− SKIP_TOKEN(parser);
875− return 1;
876− }
877−
878− else
879− {
880− return yaml_parser_set_parser_error_context(parser,
881− "while parsing a block mapping", POP(parser, parser->marks),
882− "did not find expected key", token->start_mark);
883− }
884−}
885−
886−/*
887− * Parse the productions:
888− * block_mapping ::= BLOCK-MAPPING_START
889− *
890− * ((KEY block_node_or_indentless_sequence?)?
891− *
892− * (VALUE block_node_or_indentless_sequence?)?)*
893− * ***** *
894− * BLOCK-END
895− *
896− */
897−
898−static int
899−yaml_parser_parse_block_mapping_value(yaml_parser_t *parser,
900− yaml_event_t *event)
901−{
902− yaml_token_t *token;
903−
904− token = PEEK_TOKEN(parser);
905− if (!token) return 0;
906−
907− if (token->type == YAML_VALUE_TOKEN)
908− {
909− yaml_mark_t mark = token->end_mark;
910− SKIP_TOKEN(parser);
911− token = PEEK_TOKEN(parser);
912− if (!token) return 0;
913− if (token->type != YAML_KEY_TOKEN &&
914− token->type != YAML_VALUE_TOKEN &&
915− token->type != YAML_BLOCK_END_TOKEN) {
916− if (!PUSH(parser, parser->states,
917− YAML_PARSE_BLOCK_MAPPING_KEY_STATE))
918− return 0;
919− return yaml_parser_parse_node(parser, event, 1, 1);
920− }
921− else {
922− parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
923− return yaml_parser_process_empty_scalar(parser, event, mark);
924− }
925− }
926−
927− else
928− {
929− parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
930− return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
931− }
932−}
933−
934−/*
935− * Parse the productions:
936− * flow_sequence ::= FLOW-SEQUENCE-START
937− * *******************
938− * (flow_sequence_entry FLOW-ENTRY)*
939− * * **********
940− * flow_sequence_entry?
941− * *
942− * FLOW-SEQUENCE-END
943− * *****************
944− * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
945− * *
946− */
947−
948−static int
949−yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser,
950− yaml_event_t *event, int first)
951−{
952− yaml_token_t *token;
953−
954− if (first) {
955− token = PEEK_TOKEN(parser);
956− if (!PUSH(parser, parser->marks, token->start_mark))
957− return 0;
958− SKIP_TOKEN(parser);
959− }
960−
961− token = PEEK_TOKEN(parser);
962− if (!token) return 0;
963−
964− if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN)
965− {
966− if (!first) {
967− if (token->type == YAML_FLOW_ENTRY_TOKEN) {
968− SKIP_TOKEN(parser);
969− token = PEEK_TOKEN(parser);
970− if (!token) return 0;
971− }
972− else {
973− return yaml_parser_set_parser_error_context(parser,
974− "while parsing a flow sequence", POP(parser, parser->marks),
975− "did not find expected ',' or ']'", token->start_mark);
976− }
977− }
978−
979− if (token->type == YAML_KEY_TOKEN) {
980− parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
981− MAPPING_START_EVENT_INIT(*event, NULL, NULL,
982− 1, YAML_FLOW_MAPPING_STYLE,
983− token->start_mark, token->end_mark);
984− SKIP_TOKEN(parser);
985− return 1;
986− }
987−
988− else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
989− if (!PUSH(parser, parser->states,
990− YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE))
991− return 0;
992− return yaml_parser_parse_node(parser, event, 0, 0);
993− }
994− }
995−
996− parser->state = POP(parser, parser->states);
997− (void)POP(parser, parser->marks);
998− SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
999− SKIP_TOKEN(parser);
1000− return 1;
1001−}
1002−
1003−/*
1004− * Parse the productions:
1005− * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1006− * *** *
1007− */
1008−
1009−static int
1010−yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser,
1011− yaml_event_t *event)
1012−{
1013− yaml_token_t *token;
1014−
1015− token = PEEK_TOKEN(parser);
1016− if (!token) return 0;
1017−
1018− if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN
1019− && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1020− if (!PUSH(parser, parser->states,
1021− YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE))
1022− return 0;
1023− return yaml_parser_parse_node(parser, event, 0, 0);
1024− }
1025− else {
1026− yaml_mark_t mark = token->end_mark;
1027− SKIP_TOKEN(parser);
1028− parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
1029− return yaml_parser_process_empty_scalar(parser, event, mark);
1030− }
1031−}
1032−
1033−/*
1034− * Parse the productions:
1035− * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1036− * ***** *
1037− */
1038−
1039−static int
1040−yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser,
1041− yaml_event_t *event)
1042−{
1043− yaml_token_t *token;
1044−
1045− token = PEEK_TOKEN(parser);
1046− if (!token) return 0;
1047−
1048− if (token->type == YAML_VALUE_TOKEN) {
1049− SKIP_TOKEN(parser);
1050− token = PEEK_TOKEN(parser);
1051− if (!token) return 0;
1052− if (token->type != YAML_FLOW_ENTRY_TOKEN
1053− && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) {
1054− if (!PUSH(parser, parser->states,
1055− YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE))
1056− return 0;
1057− return yaml_parser_parse_node(parser, event, 0, 0);
1058− }
1059− }
1060− parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
1061− return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1062−}
1063−
1064−/*
1065− * Parse the productions:
1066− * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1067− * *
1068− */
1069−
1070−static int
1071−yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser,
1072− yaml_event_t *event)
1073−{
1074− yaml_token_t *token;
1075−
1076− token = PEEK_TOKEN(parser);
1077− if (!token) return 0;
1078−
1079− parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
1080−
1081− MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark);
1082− return 1;
1083−}
1084−
1085−/*
1086− * Parse the productions:
1087− * flow_mapping ::= FLOW-MAPPING-START
1088− * ******************
1089− * (flow_mapping_entry FLOW-ENTRY)*
1090− * * **********
1091− * flow_mapping_entry?
1092− * ******************
1093− * FLOW-MAPPING-END
1094− * ****************
1095− * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1096− * * *** *
1097− */
1098−
1099−static int
1100−yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser,
1101− yaml_event_t *event, int first)
1102−{
1103− yaml_token_t *token;
1104−
1105− if (first) {
1106− token = PEEK_TOKEN(parser);
1107− if (!PUSH(parser, parser->marks, token->start_mark))
1108− return 0;
1109− SKIP_TOKEN(parser);
1110− }
1111−
1112− token = PEEK_TOKEN(parser);
1113− if (!token) return 0;
1114−
1115− if (token->type != YAML_FLOW_MAPPING_END_TOKEN)
1116− {
1117− if (!first) {
1118− if (token->type == YAML_FLOW_ENTRY_TOKEN) {
1119− SKIP_TOKEN(parser);
1120− token = PEEK_TOKEN(parser);
1121− if (!token) return 0;
1122− }
1123− else {
1124− return yaml_parser_set_parser_error_context(parser,
1125− "while parsing a flow mapping", POP(parser, parser->marks),
1126− "did not find expected ',' or '}'", token->start_mark);
1127− }
1128− }
1129−
1130− if (token->type == YAML_KEY_TOKEN) {
1131− SKIP_TOKEN(parser);
1132− token = PEEK_TOKEN(parser);
1133− if (!token) return 0;
1134− if (token->type != YAML_VALUE_TOKEN
1135− && token->type != YAML_FLOW_ENTRY_TOKEN
1136− && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1137− if (!PUSH(parser, parser->states,
1138− YAML_PARSE_FLOW_MAPPING_VALUE_STATE))
1139− return 0;
1140− return yaml_parser_parse_node(parser, event, 0, 0);
1141− }
1142− else {
1143− parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
1144− return yaml_parser_process_empty_scalar(parser, event,
1145− token->start_mark);
1146− }
1147− }
1148− else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1149− if (!PUSH(parser, parser->states,
1150− YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE))
1151− return 0;
1152− return yaml_parser_parse_node(parser, event, 0, 0);
1153− }
1154− }
1155−
1156− parser->state = POP(parser, parser->states);
1157− (void)POP(parser, parser->marks);
1158− MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark);
1159− SKIP_TOKEN(parser);
1160− return 1;
1161−}
1162−
1163−/*
1164− * Parse the productions:
1165− * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)?
1166− * * ***** *
1167− */
1168−
1169−static int
1170−yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser,
1171− yaml_event_t *event, int empty)
1172−{
1173− yaml_token_t *token;
1174−
1175− token = PEEK_TOKEN(parser);
1176− if (!token) return 0;
1177−
1178− if (empty) {
1179− parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1180− return yaml_parser_process_empty_scalar(parser, event,
1181− token->start_mark);
1182− }
1183−
1184− if (token->type == YAML_VALUE_TOKEN) {
1185− SKIP_TOKEN(parser);
1186− token = PEEK_TOKEN(parser);
1187− if (!token) return 0;
1188− if (token->type != YAML_FLOW_ENTRY_TOKEN
1189− && token->type != YAML_FLOW_MAPPING_END_TOKEN) {
1190− if (!PUSH(parser, parser->states,
1191− YAML_PARSE_FLOW_MAPPING_KEY_STATE))
1192− return 0;
1193− return yaml_parser_parse_node(parser, event, 0, 0);
1194− }
1195− }
1196−
1197− parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
1198− return yaml_parser_process_empty_scalar(parser, event, token->start_mark);
1199−}
1200−
1201−/*
1202− * Generate an empty scalar event.
1203− */
1204−
1205−static int
1206−yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event,
1207− yaml_mark_t mark)
1208−{
1209− yaml_char_t *value;
1210−
1211− value = YAML_MALLOC(1);
1212− if (!value) {
1213− parser->error = YAML_MEMORY_ERROR;
1214− return 0;
1215− }
1216− value[0] = '\0';
1217−
1218− SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0,
1219− 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark);
1220−
1221− return 1;
1222−}
1223−
1224−/*
1225− * Parse directives.
1226− */
1227−
1228−static int
1229−yaml_parser_process_directives(yaml_parser_t *parser,
1230− yaml_version_directive_t **version_directive_ref,
1231− yaml_tag_directive_t **tag_directives_start_ref,
1232− yaml_tag_directive_t **tag_directives_end_ref)
1233−{
1234− yaml_tag_directive_t default_tag_directives[] = {
1235− {(yaml_char_t *)"!", (yaml_char_t *)"!"},
1236− {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"},
1237− {NULL, NULL}
1238− };
1239− yaml_tag_directive_t *default_tag_directive;
1240− yaml_version_directive_t *version_directive = NULL;
1241− struct {
1242− yaml_tag_directive_t *start;
1243− yaml_tag_directive_t *end;
1244− yaml_tag_directive_t *top;
1245− } tag_directives = { NULL, NULL, NULL };
1246− yaml_token_t *token;
1247−
1248− if (!STACK_INIT(parser, tag_directives, yaml_tag_directive_t*))
1249− goto error;
1250−
1251− token = PEEK_TOKEN(parser);
1252− if (!token) goto error;
1253−
1254− while (token->type == YAML_VERSION_DIRECTIVE_TOKEN ||
1255− token->type == YAML_TAG_DIRECTIVE_TOKEN)
1256− {
1257− if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) {
1258− if (version_directive) {
1259− yaml_parser_set_parser_error(parser,
1260− "found duplicate %YAML directive", token->start_mark);
1261− goto error;
1262− }
1263− if (token->data.version_directive.major != 1
1264− || token->data.version_directive.minor != 1) {
1265− yaml_parser_set_parser_error(parser,
1266− "found incompatible YAML document", token->start_mark);
1267− goto error;
1268− }
1269− version_directive = YAML_MALLOC_STATIC(yaml_version_directive_t);
1270− if (!version_directive) {
1271− parser->error = YAML_MEMORY_ERROR;
1272− goto error;
1273− }
1274− version_directive->major = token->data.version_directive.major;
1275− version_directive->minor = token->data.version_directive.minor;
1276− }
1277−
1278− else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) {
1279− yaml_tag_directive_t value;
1280− value.handle = token->data.tag_directive.handle;
1281− value.prefix = token->data.tag_directive.prefix;
1282−
1283− if (!yaml_parser_append_tag_directive(parser, value, 0,
1284− token->start_mark))
1285− goto error;
1286− if (!PUSH(parser, tag_directives, value))
1287− goto error;
1288− }
1289−
1290− SKIP_TOKEN(parser);
1291− token = PEEK_TOKEN(parser);
1292− if (!token) goto error;
1293− }
1294−
1295− for (default_tag_directive = default_tag_directives;
1296− default_tag_directive->handle; default_tag_directive++) {
1297− if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1,
1298− token->start_mark))
1299− goto error;
1300− }
1301−
1302− if (version_directive_ref) {
1303− *version_directive_ref = version_directive;
1304− }
1305− if (tag_directives_start_ref) {
1306− if (STACK_EMPTY(parser, tag_directives)) {
1307− *tag_directives_start_ref = *tag_directives_end_ref = NULL;
1308− STACK_DEL(parser, tag_directives);
1309− }
1310− else {
1311− *tag_directives_start_ref = tag_directives.start;
1312− *tag_directives_end_ref = tag_directives.top;
1313− }
1314− }
1315− else {
1316− STACK_DEL(parser, tag_directives);
1317− }
1318−
1319− return 1;
1320−
1321−error:
1322− yaml_free(version_directive);
1323− while (!STACK_EMPTY(parser, tag_directives)) {
1324− yaml_tag_directive_t tag_directive = POP(parser, tag_directives);
1325− yaml_free(tag_directive.handle);
1326− yaml_free(tag_directive.prefix);
1327− }
1328− STACK_DEL(parser, tag_directives);
1329− return 0;
1330−}
1331−
1332−/*
1333− * Append a tag directive to the directives stack.
1334− */
1335−
1336−static int
1337−yaml_parser_append_tag_directive(yaml_parser_t *parser,
1338− yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark)
1339−{
1340− yaml_tag_directive_t *tag_directive;
1341− yaml_tag_directive_t copy = { NULL, NULL };
1342−
1343− for (tag_directive = parser->tag_directives.start;
1344− tag_directive != parser->tag_directives.top; tag_directive ++) {
1345− if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) {
1346− if (allow_duplicates)
1347− return 1;
1348− return yaml_parser_set_parser_error(parser,
1349− "found duplicate %TAG directive", mark);
1350− }
1351− }
1352−
1353− copy.handle = yaml_strdup(value.handle);
1354− copy.prefix = yaml_strdup(value.prefix);
1355− if (!copy.handle || !copy.prefix) {
1356− parser->error = YAML_MEMORY_ERROR;
1357− goto error;
1358− }
1359−
1360− if (!PUSH(parser, parser->tag_directives, copy))
1361− goto error;
1362−
1363− return 1;
1364−
1365−error:
1366− yaml_free(copy.handle);
1367− yaml_free(copy.prefix);
1368− return 0;
1369−}
1370−
libyaml/reader.cdeleted−469
@@ -1,469 +0,0 @@
1−
2−#include "yaml_private.h"
3−
4−/*
5− * Declarations.
6− */
7−
8−static int
9−yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
10− size_t offset, int value);
11−
12−static int
13−yaml_parser_update_raw_buffer(yaml_parser_t *parser);
14−
15−static int
16−yaml_parser_determine_encoding(yaml_parser_t *parser);
17−
18−YAML_DECLARE(int)
19−yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
20−
21−/*
22− * Set the reader error and return 0.
23− */
24−
25−static int
26−yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
27− size_t offset, int value)
28−{
29− parser->error = YAML_READER_ERROR;
30− parser->problem = problem;
31− parser->problem_offset = offset;
32− parser->problem_value = value;
33−
34− return 0;
35−}
36−
37−/*
38− * Byte order marks.
39− */
40−
41−#define BOM_UTF8 "\xef\xbb\xbf"
42−#define BOM_UTF16LE "\xff\xfe"
43−#define BOM_UTF16BE "\xfe\xff"
44−
45−/*
46− * Determine the input stream encoding by checking the BOM symbol. If no BOM is
47− * found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
48− */
49−
50−static int
51−yaml_parser_determine_encoding(yaml_parser_t *parser)
52−{
53− /* Ensure that we had enough bytes in the raw buffer. */
54−
55− while (!parser->eof
56− && parser->raw_buffer.last - parser->raw_buffer.pointer < 3) {
57− if (!yaml_parser_update_raw_buffer(parser)) {
58− return 0;
59− }
60− }
61−
62− /* Determine the encoding. */
63−
64− if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
65− && !memcmp(parser->raw_buffer.pointer, BOM_UTF16LE, 2)) {
66− parser->encoding = YAML_UTF16LE_ENCODING;
67− parser->raw_buffer.pointer += 2;
68− parser->offset += 2;
69− }
70− else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
71− && !memcmp(parser->raw_buffer.pointer, BOM_UTF16BE, 2)) {
72− parser->encoding = YAML_UTF16BE_ENCODING;
73− parser->raw_buffer.pointer += 2;
74− parser->offset += 2;
75− }
76− else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 3
77− && !memcmp(parser->raw_buffer.pointer, BOM_UTF8, 3)) {
78− parser->encoding = YAML_UTF8_ENCODING;
79− parser->raw_buffer.pointer += 3;
80− parser->offset += 3;
81− }
82− else {
83− parser->encoding = YAML_UTF8_ENCODING;
84− }
85−
86− return 1;
87−}
88−
89−/*
90− * Update the raw buffer.
91− */
92−
93−static int
94−yaml_parser_update_raw_buffer(yaml_parser_t *parser)
95−{
96− size_t size_read = 0;
97−
98− /* Return if the raw buffer is full. */
99−
100− if (parser->raw_buffer.start == parser->raw_buffer.pointer
101− && parser->raw_buffer.last == parser->raw_buffer.end)
102− return 1;
103−
104− /* Return on EOF. */
105−
106− if (parser->eof) return 1;
107−
108− /* Move the remaining bytes in the raw buffer to the beginning. */
109−
110− if (parser->raw_buffer.start < parser->raw_buffer.pointer
111− && parser->raw_buffer.pointer < parser->raw_buffer.last) {
112− memmove(parser->raw_buffer.start, parser->raw_buffer.pointer,
113− parser->raw_buffer.last - parser->raw_buffer.pointer);
114− }
115− parser->raw_buffer.last -=
116− parser->raw_buffer.pointer - parser->raw_buffer.start;
117− parser->raw_buffer.pointer = parser->raw_buffer.start;
118−
119− /* Call the read handler to fill the buffer. */
120−
121− if (!parser->read_handler(parser->read_handler_data, parser->raw_buffer.last,
122− parser->raw_buffer.end - parser->raw_buffer.last, &size_read)) {
123− return yaml_parser_set_reader_error(parser, "input error",
124− parser->offset, -1);
125− }
126− parser->raw_buffer.last += size_read;
127− if (!size_read) {
128− parser->eof = 1;
129− }
130−
131− return 1;
132−}
133−
134−/*
135− * Ensure that the buffer contains at least `length` characters.
136− * Return 1 on success, 0 on failure.
137− *
138− * The length is supposed to be significantly less that the buffer size.
139− */
140−
141−YAML_DECLARE(int)
142−yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
143−{
144− int first = 1;
145−
146− assert(parser->read_handler); /* Read handler must be set. */
147−
148− /* If the EOF flag is set and the raw buffer is empty, do nothing. */
149−
150− if (parser->eof && parser->raw_buffer.pointer == parser->raw_buffer.last)
151− return 1;
152−
153− /* Return if the buffer contains enough characters. */
154−
155− if (parser->unread >= length)
156− return 1;
157−
158− /* Determine the input encoding if it is not known yet. */
159−
160− if (!parser->encoding) {
161− if (!yaml_parser_determine_encoding(parser))
162− return 0;
163− }
164−
165− /* Move the unread characters to the beginning of the buffer. */
166−
167− if (parser->buffer.start < parser->buffer.pointer
168− && parser->buffer.pointer < parser->buffer.last) {
169− size_t size = parser->buffer.last - parser->buffer.pointer;
170− memmove(parser->buffer.start, parser->buffer.pointer, size);
171− parser->buffer.pointer = parser->buffer.start;
172− parser->buffer.last = parser->buffer.start + size;
173− }
174− else if (parser->buffer.pointer == parser->buffer.last) {
175− parser->buffer.pointer = parser->buffer.start;
176− parser->buffer.last = parser->buffer.start;
177− }
178−
179− /* Fill the buffer until it has enough characters. */
180−
181− while (parser->unread < length)
182− {
183− /* Fill the raw buffer if necessary. */
184−
185− if (!first || parser->raw_buffer.pointer == parser->raw_buffer.last) {
186− if (!yaml_parser_update_raw_buffer(parser)) return 0;
187− }
188− first = 0;
189−
190− /* Decode the raw buffer. */
191−
192− while (parser->raw_buffer.pointer != parser->raw_buffer.last)
193− {
194− unsigned int value = 0, value2 = 0;
195− int incomplete = 0;
196− unsigned char octet;
197− unsigned int width = 0;
198− int low, high;
199− size_t k;
200− size_t raw_unread = parser->raw_buffer.last - parser->raw_buffer.pointer;
201−
202− /* Decode the next character. */
203−
204− switch (parser->encoding)
205− {
206− case YAML_UTF8_ENCODING:
207−
208− /*
209− * Decode a UTF-8 character. Check RFC 3629
210− * (http://www.ietf.org/rfc/rfc3629.txt) for more details.
211− *
212− * The following table (taken from the RFC) is used for
213− * decoding.
214− *
215− * Char. number range | UTF-8 octet sequence
216− * (hexadecimal) | (binary)
217− * --------------------+------------------------------------
218− * 0000 0000-0000 007F | 0xxxxxxx
219− * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
220− * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
221− * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
222− *
223− * Additionally, the characters in the range 0xD800-0xDFFF
224− * are prohibited as they are reserved for use with UTF-16
225− * surrogate pairs.
226− */
227−
228− /* Determine the length of the UTF-8 sequence. */
229−
230− octet = parser->raw_buffer.pointer[0];
231− width = (octet & 0x80) == 0x00 ? 1 :
232− (octet & 0xE0) == 0xC0 ? 2 :
233− (octet & 0xF0) == 0xE0 ? 3 :
234− (octet & 0xF8) == 0xF0 ? 4 : 0;
235−
236− /* Check if the leading octet is valid. */
237−
238− if (!width)
239− return yaml_parser_set_reader_error(parser,
240− "invalid leading UTF-8 octet",
241− parser->offset, octet);
242−
243− /* Check if the raw buffer contains an incomplete character. */
244−
245− if (width > raw_unread) {
246− if (parser->eof) {
247− return yaml_parser_set_reader_error(parser,
248− "incomplete UTF-8 octet sequence",
249− parser->offset, -1);
250− }
251− incomplete = 1;
252− break;
253− }
254−
255− /* Decode the leading octet. */
256−
257− value = (octet & 0x80) == 0x00 ? octet & 0x7F :
258− (octet & 0xE0) == 0xC0 ? octet & 0x1F :
259− (octet & 0xF0) == 0xE0 ? octet & 0x0F :
260− (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
261−
262− /* Check and decode the trailing octets. */
263−
264− for (k = 1; k < width; k ++)
265− {
266− octet = parser->raw_buffer.pointer[k];
267−
268− /* Check if the octet is valid. */
269−
270− if ((octet & 0xC0) != 0x80)
271− return yaml_parser_set_reader_error(parser,
272− "invalid trailing UTF-8 octet",
273− parser->offset+k, octet);
274−
275− /* Decode the octet. */
276−
277− value = (value << 6) + (octet & 0x3F);
278− }
279−
280− /* Check the length of the sequence against the value. */
281−
282− if (!((width == 1) ||
283− (width == 2 && value >= 0x80) ||
284− (width == 3 && value >= 0x800) ||
285− (width == 4 && value >= 0x10000)))
286− return yaml_parser_set_reader_error(parser,
287− "invalid length of a UTF-8 sequence",
288− parser->offset, -1);
289−
290− /* Check the range of the value. */
291−
292− if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF)
293− return yaml_parser_set_reader_error(parser,
294− "invalid Unicode character",
295− parser->offset, value);
296−
297− break;
298−
299− case YAML_UTF16LE_ENCODING:
300− case YAML_UTF16BE_ENCODING:
301−
302− low = (parser->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
303− high = (parser->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
304−
305− /*
306− * The UTF-16 encoding is not as simple as one might
307− * naively think. Check RFC 2781
308− * (http://www.ietf.org/rfc/rfc2781.txt).
309− *
310− * Normally, two subsequent bytes describe a Unicode
311− * character. However a special technique (called a
312− * surrogate pair) is used for specifying character
313− * values larger than 0xFFFF.
314− *
315− * A surrogate pair consists of two pseudo-characters:
316− * high surrogate area (0xD800-0xDBFF)
317− * low surrogate area (0xDC00-0xDFFF)
318− *
319− * The following formulas are used for decoding
320− * and encoding characters using surrogate pairs:
321− *
322− * U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
323− * U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
324− * W1 = 110110yyyyyyyyyy
325− * W2 = 110111xxxxxxxxxx
326− *
327− * where U is the character value, W1 is the high surrogate
328− * area, W2 is the low surrogate area.
329− */
330−
331− /* Check for incomplete UTF-16 character. */
332−
333− if (raw_unread < 2) {
334− if (parser->eof) {
335− return yaml_parser_set_reader_error(parser,
336− "incomplete UTF-16 character",
337− parser->offset, -1);
338− }
339− incomplete = 1;
340− break;
341− }
342−
343− /* Get the character. */
344−
345− value = parser->raw_buffer.pointer[low]
346− + (parser->raw_buffer.pointer[high] << 8);
347−
348− /* Check for unexpected low surrogate area. */
349−
350− if ((value & 0xFC00) == 0xDC00)
351− return yaml_parser_set_reader_error(parser,
352− "unexpected low surrogate area",
353− parser->offset, value);
354−
355− /* Check for a high surrogate area. */
356−
357− if ((value & 0xFC00) == 0xD800) {
358−
359− width = 4;
360−
361− /* Check for incomplete surrogate pair. */
362−
363− if (raw_unread < 4) {
364− if (parser->eof) {
365− return yaml_parser_set_reader_error(parser,
366− "incomplete UTF-16 surrogate pair",
367− parser->offset, -1);
368− }
369− incomplete = 1;
370− break;
371− }
372−
373− /* Get the next character. */
374−
375− value2 = parser->raw_buffer.pointer[low+2]
376− + (parser->raw_buffer.pointer[high+2] << 8);
377−
378− /* Check for a low surrogate area. */
379−
380− if ((value2 & 0xFC00) != 0xDC00)
381− return yaml_parser_set_reader_error(parser,
382− "expected low surrogate area",
383− parser->offset+2, value2);
384−
385− /* Generate the value of the surrogate pair. */
386−
387− value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF);
388− }
389−
390− else {
391− width = 2;
392− }
393−
394− break;
395−
396− default:
397− assert(1); /* Impossible. */
398− }
399−
400− /* Check if the raw buffer contains enough bytes to form a character. */
401−
402− if (incomplete) break;
403−
404− /*
405− * Check if the character is in the allowed range:
406− * #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
407− * | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
408− * | [#x10000-#x10FFFF] (32 bit)
409− */
410−
411− if (! (value == 0x09 || value == 0x0A || value == 0x0D
412− || (value >= 0x20 && value <= 0x7E)
413− || (value == 0x85) || (value >= 0xA0 && value <= 0xD7FF)
414− || (value >= 0xE000 && value <= 0xFFFD)
415− || (value >= 0x10000 && value <= 0x10FFFF)))
416− return yaml_parser_set_reader_error(parser,
417− "control characters are not allowed",
418− parser->offset, value);
419−
420− /* Move the raw pointers. */
421−
422− parser->raw_buffer.pointer += width;
423− parser->offset += width;
424−
425− /* Finally put the character into the buffer. */
426−
427− /* 0000 0000-0000 007F -> 0xxxxxxx */
428− if (value <= 0x7F) {
429− *(parser->buffer.last++) = value;
430− }
431− /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
432− else if (value <= 0x7FF) {
433− *(parser->buffer.last++) = 0xC0 + (value >> 6);
434− *(parser->buffer.last++) = 0x80 + (value & 0x3F);
435− }
436− /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
437− else if (value <= 0xFFFF) {
438− *(parser->buffer.last++) = 0xE0 + (value >> 12);
439− *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
440− *(parser->buffer.last++) = 0x80 + (value & 0x3F);
441− }
442− /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
443− else {
444− *(parser->buffer.last++) = 0xF0 + (value >> 18);
445− *(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F);
446− *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
447− *(parser->buffer.last++) = 0x80 + (value & 0x3F);
448− }
449−
450− parser->unread ++;
451− }
452−
453− /* On EOF, put NUL into the buffer and return. */
454−
455− if (parser->eof) {
456− *(parser->buffer.last++) = '\0';
457− parser->unread ++;
458− return 1;
459− }
460−
461− }
462−
463− if (parser->offset >= MAX_FILE_SIZE) {
464− return yaml_parser_set_reader_error(parser, "input is too long",
465− parser->offset, -1);
466− }
467−
468− return 1;
469−}
libyaml/scanner.cdeleted−3578
@@ -1,3578 +0,0 @@
1−
2−/*
3− * Introduction
4− * ************
5− *
6− * The following notes assume that you are familiar with the YAML specification
7− * (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in
8− * some cases we are less restrictive that it requires.
9− *
10− * The process of transforming a YAML stream into a sequence of events is
11− * divided on two steps: Scanning and Parsing.
12− *
13− * The Scanner transforms the input stream into a sequence of tokens, while the
14− * parser transform the sequence of tokens produced by the Scanner into a
15− * sequence of parsing events.
16− *
17− * The Scanner is rather clever and complicated. The Parser, on the contrary,
18− * is a straightforward implementation of a recursive-descendant parser (or,
19− * LL(1) parser, as it is usually called).
20− *
21− * Actually there are two issues of Scanning that might be called "clever", the
22− * rest is quite straightforward. The issues are "block collection start" and
23− * "simple keys". Both issues are explained below in details.
24− *
25− * Here the Scanning step is explained and implemented. We start with the list
26− * of all the tokens produced by the Scanner together with short descriptions.
27− *
28− * Now, tokens:
29− *
30− * STREAM-START(encoding) # The stream start.
31− * STREAM-END # The stream end.
32− * VERSION-DIRECTIVE(major,minor) # The '%YAML' directive.
33− * TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive.
34− * DOCUMENT-START # '---'
35− * DOCUMENT-END # '...'
36− * BLOCK-SEQUENCE-START # Indentation increase denoting a block
37− * BLOCK-MAPPING-START # sequence or a block mapping.
38− * BLOCK-END # Indentation decrease.
39− * FLOW-SEQUENCE-START # '['
40− * FLOW-SEQUENCE-END # ']'
41− * BLOCK-SEQUENCE-START # '{'
42− * BLOCK-SEQUENCE-END # '}'
43− * BLOCK-ENTRY # '-'
44− * FLOW-ENTRY # ','
45− * KEY # '?' or nothing (simple keys).
46− * VALUE # ':'
47− * ALIAS(anchor) # '*anchor'
48− * ANCHOR(anchor) # '&anchor'
49− * TAG(handle,suffix) # '!handle!suffix'
50− * SCALAR(value,style) # A scalar.
51− *
52− * The following two tokens are "virtual" tokens denoting the beginning and the
53− * end of the stream:
54− *
55− * STREAM-START(encoding)
56− * STREAM-END
57− *
58− * We pass the information about the input stream encoding with the
59− * STREAM-START token.
60− *
61− * The next two tokens are responsible for tags:
62− *
63− * VERSION-DIRECTIVE(major,minor)
64− * TAG-DIRECTIVE(handle,prefix)
65− *
66− * Example:
67− *
68− * %YAML 1.1
69− * %TAG ! !foo
70− * %TAG !yaml! tag:yaml.org,2002:
71− * ---
72− *
73− * The corresponding sequence of tokens:
74− *
75− * STREAM-START(utf-8)
76− * VERSION-DIRECTIVE(1,1)
77− * TAG-DIRECTIVE("!","!foo")
78− * TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:")
79− * DOCUMENT-START
80− * STREAM-END
81− *
82− * Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole
83− * line.
84− *
85− * The document start and end indicators are represented by:
86− *
87− * DOCUMENT-START
88− * DOCUMENT-END
89− *
90− * Note that if a YAML stream contains an implicit document (without '---'
91− * and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be
92− * produced.
93− *
94− * In the following examples, we present whole documents together with the
95− * produced tokens.
96− *
97− * 1. An implicit document:
98− *
99− * 'a scalar'
100− *
101− * Tokens:
102− *
103− * STREAM-START(utf-8)
104− * SCALAR("a scalar",single-quoted)
105− * STREAM-END
106− *
107− * 2. An explicit document:
108− *
109− * ---
110− * 'a scalar'
111− * ...
112− *
113− * Tokens:
114− *
115− * STREAM-START(utf-8)
116− * DOCUMENT-START
117− * SCALAR("a scalar",single-quoted)
118− * DOCUMENT-END
119− * STREAM-END
120− *
121− * 3. Several documents in a stream:
122− *
123− * 'a scalar'
124− * ---
125− * 'another scalar'
126− * ---
127− * 'yet another scalar'
128− *
129− * Tokens:
130− *
131− * STREAM-START(utf-8)
132− * SCALAR("a scalar",single-quoted)
133− * DOCUMENT-START
134− * SCALAR("another scalar",single-quoted)
135− * DOCUMENT-START
136− * SCALAR("yet another scalar",single-quoted)
137− * STREAM-END
138− *
139− * We have already introduced the SCALAR token above. The following tokens are
140− * used to describe aliases, anchors, tag, and scalars:
141− *
142− * ALIAS(anchor)
143− * ANCHOR(anchor)
144− * TAG(handle,suffix)
145− * SCALAR(value,style)
146− *
147− * The following series of examples illustrate the usage of these tokens:
148− *
149− * 1. A recursive sequence:
150− *
151− * &A [ *A ]
152− *
153− * Tokens:
154− *
155− * STREAM-START(utf-8)
156− * ANCHOR("A")
157− * FLOW-SEQUENCE-START
158− * ALIAS("A")
159− * FLOW-SEQUENCE-END
160− * STREAM-END
161− *
162− * 2. A tagged scalar:
163− *
164− * !!float "3.14" # A good approximation.
165− *
166− * Tokens:
167− *
168− * STREAM-START(utf-8)
169− * TAG("!!","float")
170− * SCALAR("3.14",double-quoted)
171− * STREAM-END
172− *
173− * 3. Various scalar styles:
174− *
175− * --- # Implicit empty plain scalars do not produce tokens.
176− * --- a plain scalar
177− * --- 'a single-quoted scalar'
178− * --- "a double-quoted scalar"
179− * --- |-
180− * a literal scalar
181− * --- >-
182− * a folded
183− * scalar
184− *
185− * Tokens:
186− *
187− * STREAM-START(utf-8)
188− * DOCUMENT-START
189− * DOCUMENT-START
190− * SCALAR("a plain scalar",plain)
191− * DOCUMENT-START
192− * SCALAR("a single-quoted scalar",single-quoted)
193− * DOCUMENT-START
194− * SCALAR("a double-quoted scalar",double-quoted)
195− * DOCUMENT-START
196− * SCALAR("a literal scalar",literal)
197− * DOCUMENT-START
198− * SCALAR("a folded scalar",folded)
199− * STREAM-END
200− *
201− * Now it's time to review collection-related tokens. We will start with
202− * flow collections:
203− *
204− * FLOW-SEQUENCE-START
205− * FLOW-SEQUENCE-END
206− * FLOW-MAPPING-START
207− * FLOW-MAPPING-END
208− * FLOW-ENTRY
209− * KEY
210− * VALUE
211− *
212− * The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and
213− * FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'
214− * correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the
215− * indicators '?' and ':', which are used for denoting mapping keys and values,
216− * are represented by the KEY and VALUE tokens.
217− *
218− * The following examples show flow collections:
219− *
220− * 1. A flow sequence:
221− *
222− * [item 1, item 2, item 3]
223− *
224− * Tokens:
225− *
226− * STREAM-START(utf-8)
227− * FLOW-SEQUENCE-START
228− * SCALAR("item 1",plain)
229− * FLOW-ENTRY
230− * SCALAR("item 2",plain)
231− * FLOW-ENTRY
232− * SCALAR("item 3",plain)
233− * FLOW-SEQUENCE-END
234− * STREAM-END
235− *
236− * 2. A flow mapping:
237− *
238− * {
239− * a simple key: a value, # Note that the KEY token is produced.
240− * ? a complex key: another value,
241− * }
242− *
243− * Tokens:
244− *
245− * STREAM-START(utf-8)
246− * FLOW-MAPPING-START
247− * KEY
248− * SCALAR("a simple key",plain)
249− * VALUE
250− * SCALAR("a value",plain)
251− * FLOW-ENTRY
252− * KEY
253− * SCALAR("a complex key",plain)
254− * VALUE
255− * SCALAR("another value",plain)
256− * FLOW-ENTRY
257− * FLOW-MAPPING-END
258− * STREAM-END
259− *
260− * A simple key is a key which is not denoted by the '?' indicator. Note that
261− * the Scanner still produce the KEY token whenever it encounters a simple key.
262− *
263− * For scanning block collections, the following tokens are used (note that we
264− * repeat KEY and VALUE here):
265− *
266− * BLOCK-SEQUENCE-START
267− * BLOCK-MAPPING-START
268− * BLOCK-END
269− * BLOCK-ENTRY
270− * KEY
271− * VALUE
272− *
273− * The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
274− * increase that precedes a block collection (cf. the INDENT token in Python).
275− * The token BLOCK-END denote indentation decrease that ends a block collection
276− * (cf. the DEDENT token in Python). However YAML has some syntax pecularities
277− * that makes detections of these tokens more complex.
278− *
279− * The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
280− * '-', '?', and ':' correspondingly.
281− *
282− * The following examples show how the tokens BLOCK-SEQUENCE-START,
283− * BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:
284− *
285− * 1. Block sequences:
286− *
287− * - item 1
288− * - item 2
289− * -
290− * - item 3.1
291− * - item 3.2
292− * -
293− * key 1: value 1
294− * key 2: value 2
295− *
296− * Tokens:
297− *
298− * STREAM-START(utf-8)
299− * BLOCK-SEQUENCE-START
300− * BLOCK-ENTRY
301− * SCALAR("item 1",plain)
302− * BLOCK-ENTRY
303− * SCALAR("item 2",plain)
304− * BLOCK-ENTRY
305− * BLOCK-SEQUENCE-START
306− * BLOCK-ENTRY
307− * SCALAR("item 3.1",plain)
308− * BLOCK-ENTRY
309− * SCALAR("item 3.2",plain)
310− * BLOCK-END
311− * BLOCK-ENTRY
312− * BLOCK-MAPPING-START
313− * KEY
314− * SCALAR("key 1",plain)
315− * VALUE
316− * SCALAR("value 1",plain)
317− * KEY
318− * SCALAR("key 2",plain)
319− * VALUE
320− * SCALAR("value 2",plain)
321− * BLOCK-END
322− * BLOCK-END
323− * STREAM-END
324− *
325− * 2. Block mappings:
326− *
327− * a simple key: a value # The KEY token is produced here.
328− * ? a complex key
329− * : another value
330− * a mapping:
331− * key 1: value 1
332− * key 2: value 2
333− * a sequence:
334− * - item 1
335− * - item 2
336− *
337− * Tokens:
338− *
339− * STREAM-START(utf-8)
340− * BLOCK-MAPPING-START
341− * KEY
342− * SCALAR("a simple key",plain)
343− * VALUE
344− * SCALAR("a value",plain)
345− * KEY
346− * SCALAR("a complex key",plain)
347− * VALUE
348− * SCALAR("another value",plain)
349− * KEY
350− * SCALAR("a mapping",plain)
351− * BLOCK-MAPPING-START
352− * KEY
353− * SCALAR("key 1",plain)
354− * VALUE
355− * SCALAR("value 1",plain)
356− * KEY
357− * SCALAR("key 2",plain)
358− * VALUE
359− * SCALAR("value 2",plain)
360− * BLOCK-END
361− * KEY
362− * SCALAR("a sequence",plain)
363− * VALUE
364− * BLOCK-SEQUENCE-START
365− * BLOCK-ENTRY
366− * SCALAR("item 1",plain)
367− * BLOCK-ENTRY
368− * SCALAR("item 2",plain)
369− * BLOCK-END
370− * BLOCK-END
371− * STREAM-END
372− *
373− * YAML does not always require to start a new block collection from a new
374− * line. If the current line contains only '-', '?', and ':' indicators, a new
375− * block collection may start at the current line. The following examples
376− * illustrate this case:
377− *
378− * 1. Collections in a sequence:
379− *
380− * - - item 1
381− * - item 2
382− * - key 1: value 1
383− * key 2: value 2
384− * - ? complex key
385− * : complex value
386− *
387− * Tokens:
388− *
389− * STREAM-START(utf-8)
390− * BLOCK-SEQUENCE-START
391− * BLOCK-ENTRY
392− * BLOCK-SEQUENCE-START
393− * BLOCK-ENTRY
394− * SCALAR("item 1",plain)
395− * BLOCK-ENTRY
396− * SCALAR("item 2",plain)
397− * BLOCK-END
398− * BLOCK-ENTRY
399− * BLOCK-MAPPING-START
400− * KEY
401− * SCALAR("key 1",plain)
402− * VALUE
403− * SCALAR("value 1",plain)
404− * KEY
405− * SCALAR("key 2",plain)
406− * VALUE
407− * SCALAR("value 2",plain)
408− * BLOCK-END
409− * BLOCK-ENTRY
410− * BLOCK-MAPPING-START
411− * KEY
412− * SCALAR("complex key")
413− * VALUE
414− * SCALAR("complex value")
415− * BLOCK-END
416− * BLOCK-END
417− * STREAM-END
418− *
419− * 2. Collections in a mapping:
420− *
421− * ? a sequence
422− * : - item 1
423− * - item 2
424− * ? a mapping
425− * : key 1: value 1
426− * key 2: value 2
427− *
428− * Tokens:
429− *
430− * STREAM-START(utf-8)
431− * BLOCK-MAPPING-START
432− * KEY
433− * SCALAR("a sequence",plain)
434− * VALUE
435− * BLOCK-SEQUENCE-START
436− * BLOCK-ENTRY
437− * SCALAR("item 1",plain)
438− * BLOCK-ENTRY
439− * SCALAR("item 2",plain)
440− * BLOCK-END
441− * KEY
442− * SCALAR("a mapping",plain)
443− * VALUE
444− * BLOCK-MAPPING-START
445− * KEY
446− * SCALAR("key 1",plain)
447− * VALUE
448− * SCALAR("value 1",plain)
449− * KEY
450− * SCALAR("key 2",plain)
451− * VALUE
452− * SCALAR("value 2",plain)
453− * BLOCK-END
454− * BLOCK-END
455− * STREAM-END
456− *
457− * YAML also permits non-indented sequences if they are included into a block
458− * mapping. In this case, the token BLOCK-SEQUENCE-START is not produced:
459− *
460− * key:
461− * - item 1 # BLOCK-SEQUENCE-START is NOT produced here.
462− * - item 2
463− *
464− * Tokens:
465− *
466− * STREAM-START(utf-8)
467− * BLOCK-MAPPING-START
468− * KEY
469− * SCALAR("key",plain)
470− * VALUE
471− * BLOCK-ENTRY
472− * SCALAR("item 1",plain)
473− * BLOCK-ENTRY
474− * SCALAR("item 2",plain)
475− * BLOCK-END
476− */
477−
478−#include "yaml_private.h"
479−
480−/*
481− * Ensure that the buffer contains the required number of characters.
482− * Return 1 on success, 0 on failure (reader error or memory error).
483− */
484−
485−#define CACHE(parser,length) \
486− (parser->unread >= (length) \
487− ? 1 \
488− : yaml_parser_update_buffer(parser, (length)))
489−
490−/*
491− * Advance the buffer pointer.
492− */
493−
494−#define SKIP(parser) \
495− (parser->mark.index ++, \
496− parser->mark.column ++, \
497− parser->unread --, \
498− parser->buffer.pointer += WIDTH(parser->buffer))
499−
500−#define SKIP_LINE(parser) \
501− (IS_CRLF(parser->buffer) ? \
502− (parser->mark.index += 2, \
503− parser->mark.column = 0, \
504− parser->mark.line ++, \
505− parser->unread -= 2, \
506− parser->buffer.pointer += 2) : \
507− IS_BREAK(parser->buffer) ? \
508− (parser->mark.index ++, \
509− parser->mark.column = 0, \
510− parser->mark.line ++, \
511− parser->unread --, \
512− parser->buffer.pointer += WIDTH(parser->buffer)) : 0)
513−
514−/*
515− * Copy a character to a string buffer and advance pointers.
516− */
517−
518−#define READ(parser,string) \
519− (STRING_EXTEND(parser,string) ? \
520− (COPY(string,parser->buffer), \
521− parser->mark.index ++, \
522− parser->mark.column ++, \
523− parser->unread --, \
524− 1) : 0)
525−
526−/*
527− * Copy a line break character to a string buffer and advance pointers.
528− */
529−
530−#define READ_LINE(parser,string) \
531− (STRING_EXTEND(parser,string) ? \
532− (((CHECK_AT(parser->buffer,'\r',0) \
533− && CHECK_AT(parser->buffer,'\n',1)) ? /* CR LF -> LF */ \
534− (*((string).pointer++) = (yaml_char_t) '\n', \
535− parser->buffer.pointer += 2, \
536− parser->mark.index += 2, \
537− parser->mark.column = 0, \
538− parser->mark.line ++, \
539− parser->unread -= 2) : \
540− (CHECK_AT(parser->buffer,'\r',0) \
541− || CHECK_AT(parser->buffer,'\n',0)) ? /* CR|LF -> LF */ \
542− (*((string).pointer++) = (yaml_char_t) '\n', \
543− parser->buffer.pointer ++, \
544− parser->mark.index ++, \
545− parser->mark.column = 0, \
546− parser->mark.line ++, \
547− parser->unread --) : \
548− (CHECK_AT(parser->buffer,'\xC2',0) \
549− && CHECK_AT(parser->buffer,'\x85',1)) ? /* NEL -> LF */ \
550− (*((string).pointer++) = (yaml_char_t) '\n', \
551− parser->buffer.pointer += 2, \
552− parser->mark.index ++, \
553− parser->mark.column = 0, \
554− parser->mark.line ++, \
555− parser->unread --) : \
556− (CHECK_AT(parser->buffer,'\xE2',0) && \
557− CHECK_AT(parser->buffer,'\x80',1) && \
558− (CHECK_AT(parser->buffer,'\xA8',2) || \
559− CHECK_AT(parser->buffer,'\xA9',2))) ? /* LS|PS -> LS|PS */ \
560− (*((string).pointer++) = *(parser->buffer.pointer++), \
561− *((string).pointer++) = *(parser->buffer.pointer++), \
562− *((string).pointer++) = *(parser->buffer.pointer++), \
563− parser->mark.index ++, \
564− parser->mark.column = 0, \
565− parser->mark.line ++, \
566− parser->unread --) : 0), \
567− 1) : 0)
568−
569−/*
570− * Public API declarations.
571− */
572−
573−YAML_DECLARE(int)
574−yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
575−
576−/*
577− * Error handling.
578− */
579−
580−static int
581−yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
582− yaml_mark_t context_mark, const char *problem);
583−
584−/*
585− * High-level token API.
586− */
587−
588−YAML_DECLARE(int)
589−yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
590−
591−static int
592−yaml_parser_fetch_next_token(yaml_parser_t *parser);
593−
594−/*
595− * Potential simple keys.
596− */
597−
598−static int
599−yaml_parser_stale_simple_keys(yaml_parser_t *parser);
600−
601−static int
602−yaml_parser_save_simple_key(yaml_parser_t *parser);
603−
604−static int
605−yaml_parser_remove_simple_key(yaml_parser_t *parser);
606−
607−static int
608−yaml_parser_increase_flow_level(yaml_parser_t *parser);
609−
610−static int
611−yaml_parser_decrease_flow_level(yaml_parser_t *parser);
612−
613−/*
614− * Indentation treatment.
615− */
616−
617−static int
618−yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column,
619− ptrdiff_t number, yaml_token_type_t type, yaml_mark_t mark);
620−
621−static int
622−yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column);
623−
624−/*
625− * Token fetchers.
626− */
627−
628−static int
629−yaml_parser_fetch_stream_start(yaml_parser_t *parser);
630−
631−static int
632−yaml_parser_fetch_stream_end(yaml_parser_t *parser);
633−
634−static int
635−yaml_parser_fetch_directive(yaml_parser_t *parser);
636−
637−static int
638−yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
639− yaml_token_type_t type);
640−
641−static int
642−yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser,
643− yaml_token_type_t type);
644−
645−static int
646−yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser,
647− yaml_token_type_t type);
648−
649−static int
650−yaml_parser_fetch_flow_entry(yaml_parser_t *parser);
651−
652−static int
653−yaml_parser_fetch_block_entry(yaml_parser_t *parser);
654−
655−static int
656−yaml_parser_fetch_key(yaml_parser_t *parser);
657−
658−static int
659−yaml_parser_fetch_value(yaml_parser_t *parser);
660−
661−static int
662−yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type);
663−
664−static int
665−yaml_parser_fetch_tag(yaml_parser_t *parser);
666−
667−static int
668−yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal);
669−
670−static int
671−yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single);
672−
673−static int
674−yaml_parser_fetch_plain_scalar(yaml_parser_t *parser);
675−
676−/*
677− * Token scanners.
678− */
679−
680−static int
681−yaml_parser_scan_to_next_token(yaml_parser_t *parser);
682−
683−static int
684−yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token);
685−
686−static int
687−yaml_parser_scan_directive_name(yaml_parser_t *parser,
688− yaml_mark_t start_mark, yaml_char_t **name);
689−
690−static int
691−yaml_parser_scan_version_directive_value(yaml_parser_t *parser,
692− yaml_mark_t start_mark, int *major, int *minor);
693−
694−static int
695−yaml_parser_scan_version_directive_number(yaml_parser_t *parser,
696− yaml_mark_t start_mark, int *number);
697−
698−static int
699−yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
700− yaml_mark_t mark, yaml_char_t **handle, yaml_char_t **prefix);
701−
702−static int
703−yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token,
704− yaml_token_type_t type);
705−
706−static int
707−yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token);
708−
709−static int
710−yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
711− yaml_mark_t start_mark, yaml_char_t **handle);
712−
713−static int
714−yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
715− yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri);
716−
717−static int
718−yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
719− yaml_mark_t start_mark, yaml_string_t *string);
720−
721−static int
722−yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
723− int literal);
724−
725−static int
726−yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
727− int *indent, yaml_string_t *breaks,
728− yaml_mark_t start_mark, yaml_mark_t *end_mark);
729−
730−static int
731−yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
732− int single);
733−
734−static int
735−yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token);
736−
737−/*
738− * Get the next token.
739− */
740−
741−YAML_DECLARE(int)
742−yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token)
743−{
744− assert(parser); /* Non-NULL parser object is expected. */
745− assert(token); /* Non-NULL token object is expected. */
746−
747− /* Erase the token object. */
748−
749− memset(token, 0, sizeof(yaml_token_t));
750−
751− /* No tokens after STREAM-END or error. */
752−
753− if (parser->stream_end_produced || parser->error) {
754− return 1;
755− }
756−
757− /* Ensure that the tokens queue contains enough tokens. */
758−
759− if (!parser->token_available) {
760− if (!yaml_parser_fetch_more_tokens(parser))
761− return 0;
762− }
763−
764− /* Fetch the next token from the queue. */
765−
766− *token = DEQUEUE(parser, parser->tokens);
767− parser->token_available = 0;
768− parser->tokens_parsed ++;
769−
770− if (token->type == YAML_STREAM_END_TOKEN) {
771− parser->stream_end_produced = 1;
772− }
773−
774− return 1;
775−}
776−
777−/*
778− * Set the scanner error and return 0.
779− */
780−
781−static int
782−yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context,
783− yaml_mark_t context_mark, const char *problem)
784−{
785− parser->error = YAML_SCANNER_ERROR;
786− parser->context = context;
787− parser->context_mark = context_mark;
788− parser->problem = problem;
789− parser->problem_mark = parser->mark;
790−
791− return 0;
792−}
793−
794−/*
795− * Ensure that the tokens queue contains at least one token which can be
796− * returned to the Parser.
797− */
798−
799−YAML_DECLARE(int)
800−yaml_parser_fetch_more_tokens(yaml_parser_t *parser)
801−{
802− int need_more_tokens;
803−
804− /* While we need more tokens to fetch, do it. */
805−
806− while (1)
807− {
808− /*
809− * Check if we really need to fetch more tokens.
810− */
811−
812− need_more_tokens = 0;
813−
814− if (parser->tokens.head == parser->tokens.tail)
815− {
816− /* Queue is empty. */
817−
818− need_more_tokens = 1;
819− }
820− else
821− {
822− yaml_simple_key_t *simple_key;
823−
824− /* Check if any potential simple key may occupy the head position. */
825−
826− if (!yaml_parser_stale_simple_keys(parser))
827− return 0;
828−
829− for (simple_key = parser->simple_keys.start;
830− simple_key != parser->simple_keys.top; simple_key++) {
831− if (simple_key->possible
832− && simple_key->token_number == parser->tokens_parsed) {
833− need_more_tokens = 1;
834− break;
835− }
836− }
837− }
838−
839− /* We are finished. */
840−
841− if (!need_more_tokens)
842− break;
843−
844− /* Fetch the next token. */
845−
846− if (!yaml_parser_fetch_next_token(parser))
847− return 0;
848− }
849−
850− parser->token_available = 1;
851−
852− return 1;
853−}
854−
855−/*
856− * The dispatcher for token fetchers.
857− */
858−
859−static int
860−yaml_parser_fetch_next_token(yaml_parser_t *parser)
861−{
862− /* Ensure that the buffer is initialized. */
863−
864− if (!CACHE(parser, 1))
865− return 0;
866−
867− /* Check if we just started scanning. Fetch STREAM-START then. */
868−
869− if (!parser->stream_start_produced)
870− return yaml_parser_fetch_stream_start(parser);
871−
872− /* Eat whitespaces and comments until we reach the next token. */
873−
874− if (!yaml_parser_scan_to_next_token(parser))
875− return 0;
876−
877− /* Remove obsolete potential simple keys. */
878−
879− if (!yaml_parser_stale_simple_keys(parser))
880− return 0;
881−
882− /* Check the indentation level against the current column. */
883−
884− if (!yaml_parser_unroll_indent(parser, parser->mark.column))
885− return 0;
886−
887− /*
888− * Ensure that the buffer contains at least 4 characters. 4 is the length
889− * of the longest indicators ('--- ' and '... ').
890− */
891−
892− if (!CACHE(parser, 4))
893− return 0;
894−
895− /* Is it the end of the stream? */
896−
897− if (IS_Z(parser->buffer))
898− return yaml_parser_fetch_stream_end(parser);
899−
900− /* Is it a directive? */
901−
902− if (parser->mark.column == 0 && CHECK(parser->buffer, '%'))
903− return yaml_parser_fetch_directive(parser);
904−
905− /* Is it the document start indicator? */
906−
907− if (parser->mark.column == 0
908− && CHECK_AT(parser->buffer, '-', 0)
909− && CHECK_AT(parser->buffer, '-', 1)
910− && CHECK_AT(parser->buffer, '-', 2)
911− && IS_BLANKZ_AT(parser->buffer, 3))
912− return yaml_parser_fetch_document_indicator(parser,
913− YAML_DOCUMENT_START_TOKEN);
914−
915− /* Is it the document end indicator? */
916−
917− if (parser->mark.column == 0
918− && CHECK_AT(parser->buffer, '.', 0)
919− && CHECK_AT(parser->buffer, '.', 1)
920− && CHECK_AT(parser->buffer, '.', 2)
921− && IS_BLANKZ_AT(parser->buffer, 3))
922− return yaml_parser_fetch_document_indicator(parser,
923− YAML_DOCUMENT_END_TOKEN);
924−
925− /* Is it the flow sequence start indicator? */
926−
927− if (CHECK(parser->buffer, '['))
928− return yaml_parser_fetch_flow_collection_start(parser,
929− YAML_FLOW_SEQUENCE_START_TOKEN);
930−
931− /* Is it the flow mapping start indicator? */
932−
933− if (CHECK(parser->buffer, '{'))
934− return yaml_parser_fetch_flow_collection_start(parser,
935− YAML_FLOW_MAPPING_START_TOKEN);
936−
937− /* Is it the flow sequence end indicator? */
938−
939− if (CHECK(parser->buffer, ']'))
940− return yaml_parser_fetch_flow_collection_end(parser,
941− YAML_FLOW_SEQUENCE_END_TOKEN);
942−
943− /* Is it the flow mapping end indicator? */
944−
945− if (CHECK(parser->buffer, '}'))
946− return yaml_parser_fetch_flow_collection_end(parser,
947− YAML_FLOW_MAPPING_END_TOKEN);
948−
949− /* Is it the flow entry indicator? */
950−
951− if (CHECK(parser->buffer, ','))
952− return yaml_parser_fetch_flow_entry(parser);
953−
954− /* Is it the block entry indicator? */
955−
956− if (CHECK(parser->buffer, '-') && IS_BLANKZ_AT(parser->buffer, 1))
957− return yaml_parser_fetch_block_entry(parser);
958−
959− /* Is it the key indicator? */
960−
961− if (CHECK(parser->buffer, '?')
962− && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1)))
963− return yaml_parser_fetch_key(parser);
964−
965− /* Is it the value indicator? */
966−
967− if (CHECK(parser->buffer, ':')
968− && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1)))
969− return yaml_parser_fetch_value(parser);
970−
971− /* Is it an alias? */
972−
973− if (CHECK(parser->buffer, '*'))
974− return yaml_parser_fetch_anchor(parser, YAML_ALIAS_TOKEN);
975−
976− /* Is it an anchor? */
977−
978− if (CHECK(parser->buffer, '&'))
979− return yaml_parser_fetch_anchor(parser, YAML_ANCHOR_TOKEN);
980−
981− /* Is it a tag? */
982−
983− if (CHECK(parser->buffer, '!'))
984− return yaml_parser_fetch_tag(parser);
985−
986− /* Is it a literal scalar? */
987−
988− if (CHECK(parser->buffer, '|') && !parser->flow_level)
989− return yaml_parser_fetch_block_scalar(parser, 1);
990−
991− /* Is it a folded scalar? */
992−
993− if (CHECK(parser->buffer, '>') && !parser->flow_level)
994− return yaml_parser_fetch_block_scalar(parser, 0);
995−
996− /* Is it a single-quoted scalar? */
997−
998− if (CHECK(parser->buffer, '\''))
999− return yaml_parser_fetch_flow_scalar(parser, 1);
1000−
1001− /* Is it a double-quoted scalar? */
1002−
1003− if (CHECK(parser->buffer, '"'))
1004− return yaml_parser_fetch_flow_scalar(parser, 0);
1005−
1006− /*
1007− * Is it a plain scalar?
1008− *
1009− * A plain scalar may start with any non-blank characters except
1010− *
1011− * '-', '?', ':', ',', '[', ']', '{', '}',
1012− * '#', '&', '*', '!', '|', '>', '\'', '\"',
1013− * '%', '@', '`'.
1014− *
1015− * In the block context (and, for the '-' indicator, in the flow context
1016− * too), it may also start with the characters
1017− *
1018− * '-', '?', ':'
1019− *
1020− * if it is followed by a non-space character.
1021− *
1022− * The last rule is more restrictive than the specification requires.
1023− */
1024−
1025− if (!(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '-')
1026− || CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':')
1027− || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '[')
1028− || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
1029− || CHECK(parser->buffer, '}') || CHECK(parser->buffer, '#')
1030− || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '*')
1031− || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '|')
1032− || CHECK(parser->buffer, '>') || CHECK(parser->buffer, '\'')
1033− || CHECK(parser->buffer, '"') || CHECK(parser->buffer, '%')
1034− || CHECK(parser->buffer, '@') || CHECK(parser->buffer, '`')) ||
1035− (CHECK(parser->buffer, '-') && !IS_BLANK_AT(parser->buffer, 1)) ||
1036− (!parser->flow_level &&
1037− (CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':'))
1038− && !IS_BLANKZ_AT(parser->buffer, 1)))
1039− return yaml_parser_fetch_plain_scalar(parser);
1040−
1041− /*
1042− * If we don't determine the token type so far, it is an error.
1043− */
1044−
1045− return yaml_parser_set_scanner_error(parser,
1046− "while scanning for the next token", parser->mark,
1047− "found character that cannot start any token");
1048−}
1049−
1050−/*
1051− * Check the list of potential simple keys and remove the positions that
1052− * cannot contain simple keys anymore.
1053− */
1054−
1055−static int
1056−yaml_parser_stale_simple_keys(yaml_parser_t *parser)
1057−{
1058− yaml_simple_key_t *simple_key;
1059−
1060− /* Check for a potential simple key for each flow level. */
1061−
1062− for (simple_key = parser->simple_keys.start;
1063− simple_key != parser->simple_keys.top; simple_key ++)
1064− {
1065− /*
1066− * The specification requires that a simple key
1067− *
1068− * - is limited to a single line,
1069− * - is shorter than 1024 characters.
1070− */
1071−
1072− if (simple_key->possible
1073− && (simple_key->mark.line < parser->mark.line
1074− || simple_key->mark.index+1024 < parser->mark.index)) {
1075−
1076− /* Check if the potential simple key to be removed is required. */
1077−
1078− if (simple_key->required) {
1079− return yaml_parser_set_scanner_error(parser,
1080− "while scanning a simple key", simple_key->mark,
1081− "could not find expected ':'");
1082− }
1083−
1084− simple_key->possible = 0;
1085− }
1086− }
1087−
1088− return 1;
1089−}
1090−
1091−/*
1092− * Check if a simple key may start at the current position and add it if
1093− * needed.
1094− */
1095−
1096−static int
1097−yaml_parser_save_simple_key(yaml_parser_t *parser)
1098−{
1099− /*
1100− * A simple key is required at the current position if the scanner is in
1101− * the block context and the current column coincides with the indentation
1102− * level.
1103− */
1104−
1105− int required = (!parser->flow_level
1106− && parser->indent == (ptrdiff_t)parser->mark.column);
1107−
1108− /*
1109− * If the current position may start a simple key, save it.
1110− */
1111−
1112− if (parser->simple_key_allowed)
1113− {
1114− yaml_simple_key_t simple_key;
1115− simple_key.possible = 1;
1116− simple_key.required = required;
1117− simple_key.token_number =
1118− parser->tokens_parsed + (parser->tokens.tail - parser->tokens.head);
1119− simple_key.mark = parser->mark;
1120−
1121− if (!yaml_parser_remove_simple_key(parser)) return 0;
1122−
1123− *(parser->simple_keys.top-1) = simple_key;
1124− }
1125−
1126− return 1;
1127−}
1128−
1129−/*
1130− * Remove a potential simple key at the current flow level.
1131− */
1132−
1133−static int
1134−yaml_parser_remove_simple_key(yaml_parser_t *parser)
1135−{
1136− yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
1137−
1138− if (simple_key->possible)
1139− {
1140− /* If the key is required, it is an error. */
1141−
1142− if (simple_key->required) {
1143− return yaml_parser_set_scanner_error(parser,
1144− "while scanning a simple key", simple_key->mark,
1145− "could not find expected ':'");
1146− }
1147− }
1148−
1149− /* Remove the key from the stack. */
1150−
1151− simple_key->possible = 0;
1152−
1153− return 1;
1154−}
1155−
1156−/*
1157− * Increase the flow level and resize the simple key list if needed.
1158− */
1159−
1160−static int
1161−yaml_parser_increase_flow_level(yaml_parser_t *parser)
1162−{
1163− yaml_simple_key_t empty_simple_key = { 0, 0, 0, { 0, 0, 0 } };
1164−
1165− /* Reset the simple key on the next level. */
1166−
1167− if (!PUSH(parser, parser->simple_keys, empty_simple_key))
1168− return 0;
1169−
1170− /* Increase the flow level. */
1171−
1172− if (parser->flow_level == INT_MAX) {
1173− parser->error = YAML_MEMORY_ERROR;
1174− return 0;
1175− }
1176−
1177− parser->flow_level++;
1178−
1179− return 1;
1180−}
1181−
1182−/*
1183− * Decrease the flow level.
1184− */
1185−
1186−static int
1187−yaml_parser_decrease_flow_level(yaml_parser_t *parser)
1188−{
1189− if (parser->flow_level) {
1190− parser->flow_level --;
1191− (void)POP(parser, parser->simple_keys);
1192− }
1193−
1194− return 1;
1195−}
1196−
1197−/*
1198− * Push the current indentation level to the stack and set the new level
1199− * the current column is greater than the indentation level. In this case,
1200− * append or insert the specified token into the token queue.
1201− *
1202− */
1203−
1204−static int
1205−yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column,
1206− ptrdiff_t number, yaml_token_type_t type, yaml_mark_t mark)
1207−{
1208− yaml_token_t token;
1209−
1210− /* In the flow context, do nothing. */
1211−
1212− if (parser->flow_level)
1213− return 1;
1214−
1215− if (parser->indent < column)
1216− {
1217− /*
1218− * Push the current indentation level to the stack and set the new
1219− * indentation level.
1220− */
1221−
1222− if (!PUSH(parser, parser->indents, parser->indent))
1223− return 0;
1224−
1225− if (column > INT_MAX) {
1226− parser->error = YAML_MEMORY_ERROR;
1227− return 0;
1228− }
1229−
1230− parser->indent = column;
1231−
1232− /* Create a token and insert it into the queue. */
1233−
1234− TOKEN_INIT(token, type, mark, mark);
1235−
1236− if (number == -1) {
1237− if (!ENQUEUE(parser, parser->tokens, token))
1238− return 0;
1239− }
1240− else {
1241− if (!QUEUE_INSERT(parser,
1242− parser->tokens, number - parser->tokens_parsed, token))
1243− return 0;
1244− }
1245− }
1246−
1247− return 1;
1248−}
1249−
1250−/*
1251− * Pop indentation levels from the indents stack until the current level
1252− * becomes less or equal to the column. For each indentation level, append
1253− * the BLOCK-END token.
1254− */
1255−
1256−
1257−static int
1258−yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column)
1259−{
1260− yaml_token_t token;
1261−
1262− /* In the flow context, do nothing. */
1263−
1264− if (parser->flow_level)
1265− return 1;
1266−
1267− /* Loop through the indentation levels in the stack. */
1268−
1269− while (parser->indent > column)
1270− {
1271− /* Create a token and append it to the queue. */
1272−
1273− TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark);
1274−
1275− if (!ENQUEUE(parser, parser->tokens, token))
1276− return 0;
1277−
1278− /* Pop the indentation level. */
1279−
1280− parser->indent = POP(parser, parser->indents);
1281− }
1282−
1283− return 1;
1284−}
1285−
1286−/*
1287− * Initialize the scanner and produce the STREAM-START token.
1288− */
1289−
1290−static int
1291−yaml_parser_fetch_stream_start(yaml_parser_t *parser)
1292−{
1293− yaml_simple_key_t simple_key = { 0, 0, 0, { 0, 0, 0 } };
1294− yaml_token_t token;
1295−
1296− /* Set the initial indentation. */
1297−
1298− parser->indent = -1;
1299−
1300− /* Initialize the simple key stack. */
1301−
1302− if (!PUSH(parser, parser->simple_keys, simple_key))
1303− return 0;
1304−
1305− /* A simple key is allowed at the beginning of the stream. */
1306−
1307− parser->simple_key_allowed = 1;
1308−
1309− /* We have started. */
1310−
1311− parser->stream_start_produced = 1;
1312−
1313− /* Create the STREAM-START token and append it to the queue. */
1314−
1315− STREAM_START_TOKEN_INIT(token, parser->encoding,
1316− parser->mark, parser->mark);
1317−
1318− if (!ENQUEUE(parser, parser->tokens, token))
1319− return 0;
1320−
1321− return 1;
1322−}
1323−
1324−/*
1325− * Produce the STREAM-END token and shut down the scanner.
1326− */
1327−
1328−static int
1329−yaml_parser_fetch_stream_end(yaml_parser_t *parser)
1330−{
1331− yaml_token_t token;
1332−
1333− /* Force new line. */
1334−
1335− if (parser->mark.column != 0) {
1336− parser->mark.column = 0;
1337− parser->mark.line ++;
1338− }
1339−
1340− /* Reset the indentation level. */
1341−
1342− if (!yaml_parser_unroll_indent(parser, -1))
1343− return 0;
1344−
1345− /* Reset simple keys. */
1346−
1347− if (!yaml_parser_remove_simple_key(parser))
1348− return 0;
1349−
1350− parser->simple_key_allowed = 0;
1351−
1352− /* Create the STREAM-END token and append it to the queue. */
1353−
1354− STREAM_END_TOKEN_INIT(token, parser->mark, parser->mark);
1355−
1356− if (!ENQUEUE(parser, parser->tokens, token))
1357− return 0;
1358−
1359− return 1;
1360−}
1361−
1362−/*
1363− * Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.
1364− */
1365−
1366−static int
1367−yaml_parser_fetch_directive(yaml_parser_t *parser)
1368−{
1369− yaml_token_t token;
1370−
1371− /* Reset the indentation level. */
1372−
1373− if (!yaml_parser_unroll_indent(parser, -1))
1374− return 0;
1375−
1376− /* Reset simple keys. */
1377−
1378− if (!yaml_parser_remove_simple_key(parser))
1379− return 0;
1380−
1381− parser->simple_key_allowed = 0;
1382−
1383− /* Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. */
1384−
1385− if (!yaml_parser_scan_directive(parser, &token))
1386− return 0;
1387−
1388− /* Append the token to the queue. */
1389−
1390− if (!ENQUEUE(parser, parser->tokens, token)) {
1391− yaml_token_delete(&token);
1392− return 0;
1393− }
1394−
1395− return 1;
1396−}
1397−
1398−/*
1399− * Produce the DOCUMENT-START or DOCUMENT-END token.
1400− */
1401−
1402−static int
1403−yaml_parser_fetch_document_indicator(yaml_parser_t *parser,
1404− yaml_token_type_t type)
1405−{
1406− yaml_mark_t start_mark, end_mark;
1407− yaml_token_t token;
1408−
1409− /* Reset the indentation level. */
1410−
1411− if (!yaml_parser_unroll_indent(parser, -1))
1412− return 0;
1413−
1414− /* Reset simple keys. */
1415−
1416− if (!yaml_parser_remove_simple_key(parser))
1417− return 0;
1418−
1419− parser->simple_key_allowed = 0;
1420−
1421− /* Consume the token. */
1422−
1423− start_mark = parser->mark;
1424−
1425− SKIP(parser);
1426− SKIP(parser);
1427− SKIP(parser);
1428−
1429− end_mark = parser->mark;
1430−
1431− /* Create the DOCUMENT-START or DOCUMENT-END token. */
1432−
1433− TOKEN_INIT(token, type, start_mark, end_mark);
1434−
1435− /* Append the token to the queue. */
1436−
1437− if (!ENQUEUE(parser, parser->tokens, token))
1438− return 0;
1439−
1440− return 1;
1441−}
1442−
1443−/*
1444− * Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.
1445− */
1446−
1447−static int
1448−yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser,
1449− yaml_token_type_t type)
1450−{
1451− yaml_mark_t start_mark, end_mark;
1452− yaml_token_t token;
1453−
1454− /* The indicators '[' and '{' may start a simple key. */
1455−
1456− if (!yaml_parser_save_simple_key(parser))
1457− return 0;
1458−
1459− /* Increase the flow level. */
1460−
1461− if (!yaml_parser_increase_flow_level(parser))
1462− return 0;
1463−
1464− /* A simple key may follow the indicators '[' and '{'. */
1465−
1466− parser->simple_key_allowed = 1;
1467−
1468− /* Consume the token. */
1469−
1470− start_mark = parser->mark;
1471− SKIP(parser);
1472− end_mark = parser->mark;
1473−
1474− /* Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. */
1475−
1476− TOKEN_INIT(token, type, start_mark, end_mark);
1477−
1478− /* Append the token to the queue. */
1479−
1480− if (!ENQUEUE(parser, parser->tokens, token))
1481− return 0;
1482−
1483− return 1;
1484−}
1485−
1486−/*
1487− * Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.
1488− */
1489−
1490−static int
1491−yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser,
1492− yaml_token_type_t type)
1493−{
1494− yaml_mark_t start_mark, end_mark;
1495− yaml_token_t token;
1496−
1497− /* Reset any potential simple key on the current flow level. */
1498−
1499− if (!yaml_parser_remove_simple_key(parser))
1500− return 0;
1501−
1502− /* Decrease the flow level. */
1503−
1504− if (!yaml_parser_decrease_flow_level(parser))
1505− return 0;
1506−
1507− /* No simple keys after the indicators ']' and '}'. */
1508−
1509− parser->simple_key_allowed = 0;
1510−
1511− /* Consume the token. */
1512−
1513− start_mark = parser->mark;
1514− SKIP(parser);
1515− end_mark = parser->mark;
1516−
1517− /* Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. */
1518−
1519− TOKEN_INIT(token, type, start_mark, end_mark);
1520−
1521− /* Append the token to the queue. */
1522−
1523− if (!ENQUEUE(parser, parser->tokens, token))
1524− return 0;
1525−
1526− return 1;
1527−}
1528−
1529−/*
1530− * Produce the FLOW-ENTRY token.
1531− */
1532−
1533−static int
1534−yaml_parser_fetch_flow_entry(yaml_parser_t *parser)
1535−{
1536− yaml_mark_t start_mark, end_mark;
1537− yaml_token_t token;
1538−
1539− /* Reset any potential simple keys on the current flow level. */
1540−
1541− if (!yaml_parser_remove_simple_key(parser))
1542− return 0;
1543−
1544− /* Simple keys are allowed after ','. */
1545−
1546− parser->simple_key_allowed = 1;
1547−
1548− /* Consume the token. */
1549−
1550− start_mark = parser->mark;
1551− SKIP(parser);
1552− end_mark = parser->mark;
1553−
1554− /* Create the FLOW-ENTRY token and append it to the queue. */
1555−
1556− TOKEN_INIT(token, YAML_FLOW_ENTRY_TOKEN, start_mark, end_mark);
1557−
1558− if (!ENQUEUE(parser, parser->tokens, token))
1559− return 0;
1560−
1561− return 1;
1562−}
1563−
1564−/*
1565− * Produce the BLOCK-ENTRY token.
1566− */
1567−
1568−static int
1569−yaml_parser_fetch_block_entry(yaml_parser_t *parser)
1570−{
1571− yaml_mark_t start_mark, end_mark;
1572− yaml_token_t token;
1573−
1574− /* Check if the scanner is in the block context. */
1575−
1576− if (!parser->flow_level)
1577− {
1578− /* Check if we are allowed to start a new entry. */
1579−
1580− if (!parser->simple_key_allowed) {
1581− return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
1582− "block sequence entries are not allowed in this context");
1583− }
1584−
1585− /* Add the BLOCK-SEQUENCE-START token if needed. */
1586−
1587− if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
1588− YAML_BLOCK_SEQUENCE_START_TOKEN, parser->mark))
1589− return 0;
1590− }
1591− else
1592− {
1593− /*
1594− * It is an error for the '-' indicator to occur in the flow context,
1595− * but we let the Parser detect and report about it because the Parser
1596− * is able to point to the context.
1597− */
1598− }
1599−
1600− /* Reset any potential simple keys on the current flow level. */
1601−
1602− if (!yaml_parser_remove_simple_key(parser))
1603− return 0;
1604−
1605− /* Simple keys are allowed after '-'. */
1606−
1607− parser->simple_key_allowed = 1;
1608−
1609− /* Consume the token. */
1610−
1611− start_mark = parser->mark;
1612− SKIP(parser);
1613− end_mark = parser->mark;
1614−
1615− /* Create the BLOCK-ENTRY token and append it to the queue. */
1616−
1617− TOKEN_INIT(token, YAML_BLOCK_ENTRY_TOKEN, start_mark, end_mark);
1618−
1619− if (!ENQUEUE(parser, parser->tokens, token))
1620− return 0;
1621−
1622− return 1;
1623−}
1624−
1625−/*
1626− * Produce the KEY token.
1627− */
1628−
1629−static int
1630−yaml_parser_fetch_key(yaml_parser_t *parser)
1631−{
1632− yaml_mark_t start_mark, end_mark;
1633− yaml_token_t token;
1634−
1635− /* In the block context, additional checks are required. */
1636−
1637− if (!parser->flow_level)
1638− {
1639− /* Check if we are allowed to start a new key (not nessesary simple). */
1640−
1641− if (!parser->simple_key_allowed) {
1642− return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
1643− "mapping keys are not allowed in this context");
1644− }
1645−
1646− /* Add the BLOCK-MAPPING-START token if needed. */
1647−
1648− if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
1649− YAML_BLOCK_MAPPING_START_TOKEN, parser->mark))
1650− return 0;
1651− }
1652−
1653− /* Reset any potential simple keys on the current flow level. */
1654−
1655− if (!yaml_parser_remove_simple_key(parser))
1656− return 0;
1657−
1658− /* Simple keys are allowed after '?' in the block context. */
1659−
1660− parser->simple_key_allowed = (!parser->flow_level);
1661−
1662− /* Consume the token. */
1663−
1664− start_mark = parser->mark;
1665− SKIP(parser);
1666− end_mark = parser->mark;
1667−
1668− /* Create the KEY token and append it to the queue. */
1669−
1670− TOKEN_INIT(token, YAML_KEY_TOKEN, start_mark, end_mark);
1671−
1672− if (!ENQUEUE(parser, parser->tokens, token))
1673− return 0;
1674−
1675− return 1;
1676−}
1677−
1678−/*
1679− * Produce the VALUE token.
1680− */
1681−
1682−static int
1683−yaml_parser_fetch_value(yaml_parser_t *parser)
1684−{
1685− yaml_mark_t start_mark, end_mark;
1686− yaml_token_t token;
1687− yaml_simple_key_t *simple_key = parser->simple_keys.top-1;
1688−
1689− /* Have we found a simple key? */
1690−
1691− if (simple_key->possible)
1692− {
1693−
1694− /* Create the KEY token and insert it into the queue. */
1695−
1696− TOKEN_INIT(token, YAML_KEY_TOKEN, simple_key->mark, simple_key->mark);
1697−
1698− if (!QUEUE_INSERT(parser, parser->tokens,
1699− simple_key->token_number - parser->tokens_parsed, token))
1700− return 0;
1701−
1702− /* In the block context, we may need to add the BLOCK-MAPPING-START token. */
1703−
1704− if (!yaml_parser_roll_indent(parser, simple_key->mark.column,
1705− simple_key->token_number,
1706− YAML_BLOCK_MAPPING_START_TOKEN, simple_key->mark))
1707− return 0;
1708−
1709− /* Remove the simple key. */
1710−
1711− simple_key->possible = 0;
1712−
1713− /* A simple key cannot follow another simple key. */
1714−
1715− parser->simple_key_allowed = 0;
1716− }
1717− else
1718− {
1719− /* The ':' indicator follows a complex key. */
1720−
1721− /* In the block context, extra checks are required. */
1722−
1723− if (!parser->flow_level)
1724− {
1725− /* Check if we are allowed to start a complex value. */
1726−
1727− if (!parser->simple_key_allowed) {
1728− return yaml_parser_set_scanner_error(parser, NULL, parser->mark,
1729− "mapping values are not allowed in this context");
1730− }
1731−
1732− /* Add the BLOCK-MAPPING-START token if needed. */
1733−
1734− if (!yaml_parser_roll_indent(parser, parser->mark.column, -1,
1735− YAML_BLOCK_MAPPING_START_TOKEN, parser->mark))
1736− return 0;
1737− }
1738−
1739− /* Simple keys after ':' are allowed in the block context. */
1740−
1741− parser->simple_key_allowed = (!parser->flow_level);
1742− }
1743−
1744− /* Consume the token. */
1745−
1746− start_mark = parser->mark;
1747− SKIP(parser);
1748− end_mark = parser->mark;
1749−
1750− /* Create the VALUE token and append it to the queue. */
1751−
1752− TOKEN_INIT(token, YAML_VALUE_TOKEN, start_mark, end_mark);
1753−
1754− if (!ENQUEUE(parser, parser->tokens, token))
1755− return 0;
1756−
1757− return 1;
1758−}
1759−
1760−/*
1761− * Produce the ALIAS or ANCHOR token.
1762− */
1763−
1764−static int
1765−yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type)
1766−{
1767− yaml_token_t token;
1768−
1769− /* An anchor or an alias could be a simple key. */
1770−
1771− if (!yaml_parser_save_simple_key(parser))
1772− return 0;
1773−
1774− /* A simple key cannot follow an anchor or an alias. */
1775−
1776− parser->simple_key_allowed = 0;
1777−
1778− /* Create the ALIAS or ANCHOR token and append it to the queue. */
1779−
1780− if (!yaml_parser_scan_anchor(parser, &token, type))
1781− return 0;
1782−
1783− if (!ENQUEUE(parser, parser->tokens, token)) {
1784− yaml_token_delete(&token);
1785− return 0;
1786− }
1787− return 1;
1788−}
1789−
1790−/*
1791− * Produce the TAG token.
1792− */
1793−
1794−static int
1795−yaml_parser_fetch_tag(yaml_parser_t *parser)
1796−{
1797− yaml_token_t token;
1798−
1799− /* A tag could be a simple key. */
1800−
1801− if (!yaml_parser_save_simple_key(parser))
1802− return 0;
1803−
1804− /* A simple key cannot follow a tag. */
1805−
1806− parser->simple_key_allowed = 0;
1807−
1808− /* Create the TAG token and append it to the queue. */
1809−
1810− if (!yaml_parser_scan_tag(parser, &token))
1811− return 0;
1812−
1813− if (!ENQUEUE(parser, parser->tokens, token)) {
1814− yaml_token_delete(&token);
1815− return 0;
1816− }
1817−
1818− return 1;
1819−}
1820−
1821−/*
1822− * Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.
1823− */
1824−
1825−static int
1826−yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal)
1827−{
1828− yaml_token_t token;
1829−
1830− /* Remove any potential simple keys. */
1831−
1832− if (!yaml_parser_remove_simple_key(parser))
1833− return 0;
1834−
1835− /* A simple key may follow a block scalar. */
1836−
1837− parser->simple_key_allowed = 1;
1838−
1839− /* Create the SCALAR token and append it to the queue. */
1840−
1841− if (!yaml_parser_scan_block_scalar(parser, &token, literal))
1842− return 0;
1843−
1844− if (!ENQUEUE(parser, parser->tokens, token)) {
1845− yaml_token_delete(&token);
1846− return 0;
1847− }
1848−
1849− return 1;
1850−}
1851−
1852−/*
1853− * Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.
1854− */
1855−
1856−static int
1857−yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single)
1858−{
1859− yaml_token_t token;
1860−
1861− /* A plain scalar could be a simple key. */
1862−
1863− if (!yaml_parser_save_simple_key(parser))
1864− return 0;
1865−
1866− /* A simple key cannot follow a flow scalar. */
1867−
1868− parser->simple_key_allowed = 0;
1869−
1870− /* Create the SCALAR token and append it to the queue. */
1871−
1872− if (!yaml_parser_scan_flow_scalar(parser, &token, single))
1873− return 0;
1874−
1875− if (!ENQUEUE(parser, parser->tokens, token)) {
1876− yaml_token_delete(&token);
1877− return 0;
1878− }
1879−
1880− return 1;
1881−}
1882−
1883−/*
1884− * Produce the SCALAR(...,plain) token.
1885− */
1886−
1887−static int
1888−yaml_parser_fetch_plain_scalar(yaml_parser_t *parser)
1889−{
1890− yaml_token_t token;
1891−
1892− /* A plain scalar could be a simple key. */
1893−
1894− if (!yaml_parser_save_simple_key(parser))
1895− return 0;
1896−
1897− /* A simple key cannot follow a flow scalar. */
1898−
1899− parser->simple_key_allowed = 0;
1900−
1901− /* Create the SCALAR token and append it to the queue. */
1902−
1903− if (!yaml_parser_scan_plain_scalar(parser, &token))
1904− return 0;
1905−
1906− if (!ENQUEUE(parser, parser->tokens, token)) {
1907− yaml_token_delete(&token);
1908− return 0;
1909− }
1910−
1911− return 1;
1912−}
1913−
1914−/*
1915− * Eat whitespaces and comments until the next token is found.
1916− */
1917−
1918−static int
1919−yaml_parser_scan_to_next_token(yaml_parser_t *parser)
1920−{
1921− /* Until the next token is not found. */
1922−
1923− while (1)
1924− {
1925− /* Allow the BOM mark to start a line. */
1926−
1927− if (!CACHE(parser, 1)) return 0;
1928−
1929− if (parser->mark.column == 0 && IS_BOM(parser->buffer))
1930− SKIP(parser);
1931−
1932− /*
1933− * Eat whitespaces.
1934− *
1935− * Tabs are allowed:
1936− *
1937− * - in the flow context;
1938− * - in the block context, but not at the beginning of the line or
1939− * after '-', '?', or ':' (complex value).
1940− */
1941−
1942− if (!CACHE(parser, 1)) return 0;
1943−
1944− while (CHECK(parser->buffer,' ') ||
1945− ((parser->flow_level || !parser->simple_key_allowed) &&
1946− CHECK(parser->buffer, '\t'))) {
1947− SKIP(parser);
1948− if (!CACHE(parser, 1)) return 0;
1949− }
1950−
1951− /* Eat a comment until a line break. */
1952−
1953− if (CHECK(parser->buffer, '#')) {
1954− while (!IS_BREAKZ(parser->buffer)) {
1955− SKIP(parser);
1956− if (!CACHE(parser, 1)) return 0;
1957− }
1958− }
1959−
1960− /* If it is a line break, eat it. */
1961−
1962− if (IS_BREAK(parser->buffer))
1963− {
1964− if (!CACHE(parser, 2)) return 0;
1965− SKIP_LINE(parser);
1966−
1967− /* In the block context, a new line may start a simple key. */
1968−
1969− if (!parser->flow_level) {
1970− parser->simple_key_allowed = 1;
1971− }
1972− }
1973− else
1974− {
1975− /* We have found a token. */
1976−
1977− break;
1978− }
1979− }
1980−
1981− return 1;
1982−}
1983−
1984−/*
1985− * Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.
1986− *
1987− * Scope:
1988− * %YAML 1.1 # a comment \n
1989− * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1990− * %TAG !yaml! tag:yaml.org,2002: \n
1991− * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1992− */
1993−
1994−int
1995−yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token)
1996−{
1997− yaml_mark_t start_mark, end_mark;
1998− yaml_char_t *name = NULL;
1999− int major, minor;
2000− yaml_char_t *handle = NULL, *prefix = NULL;
2001−
2002− /* Eat '%'. */
2003−
2004− start_mark = parser->mark;
2005−
2006− SKIP(parser);
2007−
2008− /* Scan the directive name. */
2009−
2010− if (!yaml_parser_scan_directive_name(parser, start_mark, &name))
2011− goto error;
2012−
2013− /* Is it a YAML directive? */
2014−
2015− if (strcmp((char *)name, "YAML") == 0)
2016− {
2017− /* Scan the VERSION directive value. */
2018−
2019− if (!yaml_parser_scan_version_directive_value(parser, start_mark,
2020− &major, &minor))
2021− goto error;
2022−
2023− end_mark = parser->mark;
2024−
2025− /* Create a VERSION-DIRECTIVE token. */
2026−
2027− VERSION_DIRECTIVE_TOKEN_INIT(*token, major, minor,
2028− start_mark, end_mark);
2029− }
2030−
2031− /* Is it a TAG directive? */
2032−
2033− else if (strcmp((char *)name, "TAG") == 0)
2034− {
2035− /* Scan the TAG directive value. */
2036−
2037− if (!yaml_parser_scan_tag_directive_value(parser, start_mark,
2038− &handle, &prefix))
2039− goto error;
2040−
2041− end_mark = parser->mark;
2042−
2043− /* Create a TAG-DIRECTIVE token. */
2044−
2045− TAG_DIRECTIVE_TOKEN_INIT(*token, handle, prefix,
2046− start_mark, end_mark);
2047− }
2048−
2049− /* Unknown directive. */
2050−
2051− else
2052− {
2053− yaml_parser_set_scanner_error(parser, "while scanning a directive",
2054− start_mark, "found unknown directive name");
2055− goto error;
2056− }
2057−
2058− /* Eat the rest of the line including any comments. */
2059−
2060− if (!CACHE(parser, 1)) goto error;
2061−
2062− while (IS_BLANK(parser->buffer)) {
2063− SKIP(parser);
2064− if (!CACHE(parser, 1)) goto error;
2065− }
2066−
2067− if (CHECK(parser->buffer, '#')) {
2068− while (!IS_BREAKZ(parser->buffer)) {
2069− SKIP(parser);
2070− if (!CACHE(parser, 1)) goto error;
2071− }
2072− }
2073−
2074− /* Check if we are at the end of the line. */
2075−
2076− if (!IS_BREAKZ(parser->buffer)) {
2077− yaml_parser_set_scanner_error(parser, "while scanning a directive",
2078− start_mark, "did not find expected comment or line break");
2079− goto error;
2080− }
2081−
2082− /* Eat a line break. */
2083−
2084− if (IS_BREAK(parser->buffer)) {
2085− if (!CACHE(parser, 2)) goto error;
2086− SKIP_LINE(parser);
2087− }
2088−
2089− yaml_free(name);
2090−
2091− return 1;
2092−
2093−error:
2094− yaml_free(prefix);
2095− yaml_free(handle);
2096− yaml_free(name);
2097− return 0;
2098−}
2099−
2100−/*
2101− * Scan the directive name.
2102− *
2103− * Scope:
2104− * %YAML 1.1 # a comment \n
2105− * ^^^^
2106− * %TAG !yaml! tag:yaml.org,2002: \n
2107− * ^^^
2108− */
2109−
2110−static int
2111−yaml_parser_scan_directive_name(yaml_parser_t *parser,
2112− yaml_mark_t start_mark, yaml_char_t **name)
2113−{
2114− yaml_string_t string = NULL_STRING;
2115−
2116− if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
2117−
2118− /* Consume the directive name. */
2119−
2120− if (!CACHE(parser, 1)) goto error;
2121−
2122− while (IS_ALPHA(parser->buffer))
2123− {
2124− if (!READ(parser, string)) goto error;
2125− if (!CACHE(parser, 1)) goto error;
2126− }
2127−
2128− /* Check if the name is empty. */
2129−
2130− if (string.start == string.pointer) {
2131− yaml_parser_set_scanner_error(parser, "while scanning a directive",
2132− start_mark, "could not find expected directive name");
2133− goto error;
2134− }
2135−
2136− /* Check for an blank character after the name. */
2137−
2138− if (!IS_BLANKZ(parser->buffer)) {
2139− yaml_parser_set_scanner_error(parser, "while scanning a directive",
2140− start_mark, "found unexpected non-alphabetical character");
2141− goto error;
2142− }
2143−
2144− *name = string.start;
2145−
2146− return 1;
2147−
2148−error:
2149− STRING_DEL(parser, string);
2150− return 0;
2151−}
2152−
2153−/*
2154− * Scan the value of VERSION-DIRECTIVE.
2155− *
2156− * Scope:
2157− * %YAML 1.1 # a comment \n
2158− * ^^^^^^
2159− */
2160−
2161−static int
2162−yaml_parser_scan_version_directive_value(yaml_parser_t *parser,
2163− yaml_mark_t start_mark, int *major, int *minor)
2164−{
2165− /* Eat whitespaces. */
2166−
2167− if (!CACHE(parser, 1)) return 0;
2168−
2169− while (IS_BLANK(parser->buffer)) {
2170− SKIP(parser);
2171− if (!CACHE(parser, 1)) return 0;
2172− }
2173−
2174− /* Consume the major version number. */
2175−
2176− if (!yaml_parser_scan_version_directive_number(parser, start_mark, major))
2177− return 0;
2178−
2179− /* Eat '.'. */
2180−
2181− if (!CHECK(parser->buffer, '.')) {
2182− return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
2183− start_mark, "did not find expected digit or '.' character");
2184− }
2185−
2186− SKIP(parser);
2187−
2188− /* Consume the minor version number. */
2189−
2190− if (!yaml_parser_scan_version_directive_number(parser, start_mark, minor))
2191− return 0;
2192−
2193− return 1;
2194−}
2195−
2196−#define MAX_NUMBER_LENGTH 9
2197−
2198−/*
2199− * Scan the version number of VERSION-DIRECTIVE.
2200− *
2201− * Scope:
2202− * %YAML 1.1 # a comment \n
2203− * ^
2204− * %YAML 1.1 # a comment \n
2205− * ^
2206− */
2207−
2208−static int
2209−yaml_parser_scan_version_directive_number(yaml_parser_t *parser,
2210− yaml_mark_t start_mark, int *number)
2211−{
2212− int value = 0;
2213− size_t length = 0;
2214−
2215− /* Repeat while the next character is digit. */
2216−
2217− if (!CACHE(parser, 1)) return 0;
2218−
2219− while (IS_DIGIT(parser->buffer))
2220− {
2221− /* Check if the number is too long. */
2222−
2223− if (++length > MAX_NUMBER_LENGTH) {
2224− return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
2225− start_mark, "found extremely long version number");
2226− }
2227−
2228− value = value*10 + AS_DIGIT(parser->buffer);
2229−
2230− SKIP(parser);
2231−
2232− if (!CACHE(parser, 1)) return 0;
2233− }
2234−
2235− /* Check if the number was present. */
2236−
2237− if (!length) {
2238− return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive",
2239− start_mark, "did not find expected version number");
2240− }
2241−
2242− *number = value;
2243−
2244− return 1;
2245−}
2246−
2247−/*
2248− * Scan the value of a TAG-DIRECTIVE token.
2249− *
2250− * Scope:
2251− * %TAG !yaml! tag:yaml.org,2002: \n
2252− * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2253− */
2254−
2255−static int
2256−yaml_parser_scan_tag_directive_value(yaml_parser_t *parser,
2257− yaml_mark_t start_mark, yaml_char_t **handle, yaml_char_t **prefix)
2258−{
2259− yaml_char_t *handle_value = NULL;
2260− yaml_char_t *prefix_value = NULL;
2261−
2262− /* Eat whitespaces. */
2263−
2264− if (!CACHE(parser, 1)) goto error;
2265−
2266− while (IS_BLANK(parser->buffer)) {
2267− SKIP(parser);
2268− if (!CACHE(parser, 1)) goto error;
2269− }
2270−
2271− /* Scan a handle. */
2272−
2273− if (!yaml_parser_scan_tag_handle(parser, 1, start_mark, &handle_value))
2274− goto error;
2275−
2276− /* Expect a whitespace. */
2277−
2278− if (!CACHE(parser, 1)) goto error;
2279−
2280− if (!IS_BLANK(parser->buffer)) {
2281− yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
2282− start_mark, "did not find expected whitespace");
2283− goto error;
2284− }
2285−
2286− /* Eat whitespaces. */
2287−
2288− while (IS_BLANK(parser->buffer)) {
2289− SKIP(parser);
2290− if (!CACHE(parser, 1)) goto error;
2291− }
2292−
2293− /* Scan a prefix. */
2294−
2295− if (!yaml_parser_scan_tag_uri(parser, 1, NULL, start_mark, &prefix_value))
2296− goto error;
2297−
2298− /* Expect a whitespace or line break. */
2299−
2300− if (!CACHE(parser, 1)) goto error;
2301−
2302− if (!IS_BLANKZ(parser->buffer)) {
2303− yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive",
2304− start_mark, "did not find expected whitespace or line break");
2305− goto error;
2306− }
2307−
2308− *handle = handle_value;
2309− *prefix = prefix_value;
2310−
2311− return 1;
2312−
2313−error:
2314− yaml_free(handle_value);
2315− yaml_free(prefix_value);
2316− return 0;
2317−}
2318−
2319−static int
2320−yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token,
2321− yaml_token_type_t type)
2322−{
2323− int length = 0;
2324− yaml_mark_t start_mark, end_mark;
2325− yaml_string_t string = NULL_STRING;
2326−
2327− if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
2328−
2329− /* Eat the indicator character. */
2330−
2331− start_mark = parser->mark;
2332−
2333− SKIP(parser);
2334−
2335− /* Consume the value. */
2336−
2337− if (!CACHE(parser, 1)) goto error;
2338−
2339− while (IS_ALPHA(parser->buffer)) {
2340− if (!READ(parser, string)) goto error;
2341− if (!CACHE(parser, 1)) goto error;
2342− length ++;
2343− }
2344−
2345− end_mark = parser->mark;
2346−
2347− /*
2348− * Check if length of the anchor is greater than 0 and it is followed by
2349− * a whitespace character or one of the indicators:
2350− *
2351− * '?', ':', ',', ']', '}', '%', '@', '`'.
2352− */
2353−
2354− if (!length || !(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '?')
2355− || CHECK(parser->buffer, ':') || CHECK(parser->buffer, ',')
2356− || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '}')
2357− || CHECK(parser->buffer, '%') || CHECK(parser->buffer, '@')
2358− || CHECK(parser->buffer, '`'))) {
2359− yaml_parser_set_scanner_error(parser, type == YAML_ANCHOR_TOKEN ?
2360− "while scanning an anchor" : "while scanning an alias", start_mark,
2361− "did not find expected alphabetic or numeric character");
2362− goto error;
2363− }
2364−
2365− /* Create a token. */
2366−
2367− if (type == YAML_ANCHOR_TOKEN) {
2368− ANCHOR_TOKEN_INIT(*token, string.start, start_mark, end_mark);
2369− }
2370− else {
2371− ALIAS_TOKEN_INIT(*token, string.start, start_mark, end_mark);
2372− }
2373−
2374− return 1;
2375−
2376−error:
2377− STRING_DEL(parser, string);
2378− return 0;
2379−}
2380−
2381−/*
2382− * Scan a TAG token.
2383− */
2384−
2385−static int
2386−yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token)
2387−{
2388− yaml_char_t *handle = NULL;
2389− yaml_char_t *suffix = NULL;
2390− yaml_mark_t start_mark, end_mark;
2391−
2392− start_mark = parser->mark;
2393−
2394− /* Check if the tag is in the canonical form. */
2395−
2396− if (!CACHE(parser, 2)) goto error;
2397−
2398− if (CHECK_AT(parser->buffer, '<', 1))
2399− {
2400− /* Set the handle to '' */
2401−
2402− handle = YAML_MALLOC(1);
2403− if (!handle) goto error;
2404− handle[0] = '\0';
2405−
2406− /* Eat '!<' */
2407−
2408− SKIP(parser);
2409− SKIP(parser);
2410−
2411− /* Consume the tag value. */
2412−
2413− if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix))
2414− goto error;
2415−
2416− /* Check for '>' and eat it. */
2417−
2418− if (!CHECK(parser->buffer, '>')) {
2419− yaml_parser_set_scanner_error(parser, "while scanning a tag",
2420− start_mark, "did not find the expected '>'");
2421− goto error;
2422− }
2423−
2424− SKIP(parser);
2425− }
2426− else
2427− {
2428− /* The tag has either the '!suffix' or the '!handle!suffix' form. */
2429−
2430− /* First, try to scan a handle. */
2431−
2432− if (!yaml_parser_scan_tag_handle(parser, 0, start_mark, &handle))
2433− goto error;
2434−
2435− /* Check if it is, indeed, handle. */
2436−
2437− if (handle[0] == '!' && handle[1] != '\0' && handle[strlen((char *)handle)-1] == '!')
2438− {
2439− /* Scan the suffix now. */
2440−
2441− if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix))
2442− goto error;
2443− }
2444− else
2445− {
2446− /* It wasn't a handle after all. Scan the rest of the tag. */
2447−
2448− if (!yaml_parser_scan_tag_uri(parser, 0, handle, start_mark, &suffix))
2449− goto error;
2450−
2451− /* Set the handle to '!'. */
2452−
2453− yaml_free(handle);
2454− handle = YAML_MALLOC(2);
2455− if (!handle) goto error;
2456− handle[0] = '!';
2457− handle[1] = '\0';
2458−
2459− /*
2460− * A special case: the '!' tag. Set the handle to '' and the
2461− * suffix to '!'.
2462− */
2463−
2464− if (suffix[0] == '\0') {
2465− yaml_char_t *tmp = handle;
2466− handle = suffix;
2467− suffix = tmp;
2468− }
2469− }
2470− }
2471−
2472− /* Check the character which ends the tag. */
2473−
2474− if (!CACHE(parser, 1)) goto error;
2475−
2476− if (!IS_BLANKZ(parser->buffer)) {
2477− yaml_parser_set_scanner_error(parser, "while scanning a tag",
2478− start_mark, "did not find expected whitespace or line break");
2479− goto error;
2480− }
2481−
2482− end_mark = parser->mark;
2483−
2484− /* Create a token. */
2485−
2486− TAG_TOKEN_INIT(*token, handle, suffix, start_mark, end_mark);
2487−
2488− return 1;
2489−
2490−error:
2491− yaml_free(handle);
2492− yaml_free(suffix);
2493− return 0;
2494−}
2495−
2496−/*
2497− * Scan a tag handle.
2498− */
2499−
2500−static int
2501−yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive,
2502− yaml_mark_t start_mark, yaml_char_t **handle)
2503−{
2504− yaml_string_t string = NULL_STRING;
2505−
2506− if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
2507−
2508− /* Check the initial '!' character. */
2509−
2510− if (!CACHE(parser, 1)) goto error;
2511−
2512− if (!CHECK(parser->buffer, '!')) {
2513− yaml_parser_set_scanner_error(parser, directive ?
2514− "while scanning a tag directive" : "while scanning a tag",
2515− start_mark, "did not find expected '!'");
2516− goto error;
2517− }
2518−
2519− /* Copy the '!' character. */
2520−
2521− if (!READ(parser, string)) goto error;
2522−
2523− /* Copy all subsequent alphabetical and numerical characters. */
2524−
2525− if (!CACHE(parser, 1)) goto error;
2526−
2527− while (IS_ALPHA(parser->buffer))
2528− {
2529− if (!READ(parser, string)) goto error;
2530− if (!CACHE(parser, 1)) goto error;
2531− }
2532−
2533− /* Check if the trailing character is '!' and copy it. */
2534−
2535− if (CHECK(parser->buffer, '!'))
2536− {
2537− if (!READ(parser, string)) goto error;
2538− }
2539− else
2540− {
2541− /*
2542− * It's either the '!' tag or not really a tag handle. If it's a %TAG
2543− * directive, it's an error. If it's a tag token, it must be a part of
2544− * URI.
2545− */
2546−
2547− if (directive && !(string.start[0] == '!' && string.start[1] == '\0')) {
2548− yaml_parser_set_scanner_error(parser, "while parsing a tag directive",
2549− start_mark, "did not find expected '!'");
2550− goto error;
2551− }
2552− }
2553−
2554− *handle = string.start;
2555−
2556− return 1;
2557−
2558−error:
2559− STRING_DEL(parser, string);
2560− return 0;
2561−}
2562−
2563−/*
2564− * Scan a tag.
2565− */
2566−
2567−static int
2568−yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive,
2569− yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri)
2570−{
2571− size_t length = head ? strlen((char *)head) : 0;
2572− yaml_string_t string = NULL_STRING;
2573−
2574− if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
2575−
2576− /* Resize the string to include the head. */
2577−
2578− while ((size_t)(string.end - string.start) <= length) {
2579− if (!yaml_string_extend(&string.start, &string.pointer, &string.end)) {
2580− parser->error = YAML_MEMORY_ERROR;
2581− goto error;
2582− }
2583− }
2584−
2585− /*
2586− * Copy the head if needed.
2587− *
2588− * Note that we don't copy the leading '!' character.
2589− */
2590−
2591− if (length > 1) {
2592− memcpy(string.start, head+1, length-1);
2593− string.pointer += length-1;
2594− }
2595−
2596− /* Scan the tag. */
2597−
2598− if (!CACHE(parser, 1)) goto error;
2599−
2600− /*
2601− * The set of characters that may appear in URI is as follows:
2602− *
2603− * '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',
2604− * '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']',
2605− * '%'.
2606− */
2607−
2608− while (IS_ALPHA(parser->buffer) || CHECK(parser->buffer, ';')
2609− || CHECK(parser->buffer, '/') || CHECK(parser->buffer, '?')
2610− || CHECK(parser->buffer, ':') || CHECK(parser->buffer, '@')
2611− || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '=')
2612− || CHECK(parser->buffer, '+') || CHECK(parser->buffer, '$')
2613− || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '.')
2614− || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '~')
2615− || CHECK(parser->buffer, '*') || CHECK(parser->buffer, '\'')
2616− || CHECK(parser->buffer, '(') || CHECK(parser->buffer, ')')
2617− || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']')
2618− || CHECK(parser->buffer, '%'))
2619− {
2620− /* Check if it is a URI-escape sequence. */
2621−
2622− if (CHECK(parser->buffer, '%')) {
2623− if (!STRING_EXTEND(parser, string))
2624− goto error;
2625−
2626− if (!yaml_parser_scan_uri_escapes(parser,
2627− directive, start_mark, &string)) goto error;
2628− }
2629− else {
2630− if (!READ(parser, string)) goto error;
2631− }
2632−
2633− length ++;
2634− if (!CACHE(parser, 1)) goto error;
2635− }
2636−
2637− /* Check if the tag is non-empty. */
2638−
2639− if (!length) {
2640− if (!STRING_EXTEND(parser, string))
2641− goto error;
2642−
2643− yaml_parser_set_scanner_error(parser, directive ?
2644− "while parsing a %TAG directive" : "while parsing a tag",
2645− start_mark, "did not find expected tag URI");
2646− goto error;
2647− }
2648−
2649− *uri = string.start;
2650−
2651− return 1;
2652−
2653−error:
2654− STRING_DEL(parser, string);
2655− return 0;
2656−}
2657−
2658−/*
2659− * Decode an URI-escape sequence corresponding to a single UTF-8 character.
2660− */
2661−
2662−static int
2663−yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive,
2664− yaml_mark_t start_mark, yaml_string_t *string)
2665−{
2666− int width = 0;
2667−
2668− /* Decode the required number of characters. */
2669−
2670− do {
2671−
2672− unsigned char octet = 0;
2673−
2674− /* Check for a URI-escaped octet. */
2675−
2676− if (!CACHE(parser, 3)) return 0;
2677−
2678− if (!(CHECK(parser->buffer, '%')
2679− && IS_HEX_AT(parser->buffer, 1)
2680− && IS_HEX_AT(parser->buffer, 2))) {
2681− return yaml_parser_set_scanner_error(parser, directive ?
2682− "while parsing a %TAG directive" : "while parsing a tag",
2683− start_mark, "did not find URI escaped octet");
2684− }
2685−
2686− /* Get the octet. */
2687−
2688− octet = (AS_HEX_AT(parser->buffer, 1) << 4) + AS_HEX_AT(parser->buffer, 2);
2689−
2690− /* If it is the leading octet, determine the length of the UTF-8 sequence. */
2691−
2692− if (!width)
2693− {
2694− width = (octet & 0x80) == 0x00 ? 1 :
2695− (octet & 0xE0) == 0xC0 ? 2 :
2696− (octet & 0xF0) == 0xE0 ? 3 :
2697− (octet & 0xF8) == 0xF0 ? 4 : 0;
2698− if (!width) {
2699− return yaml_parser_set_scanner_error(parser, directive ?
2700− "while parsing a %TAG directive" : "while parsing a tag",
2701− start_mark, "found an incorrect leading UTF-8 octet");
2702− }
2703− }
2704− else
2705− {
2706− /* Check if the trailing octet is correct. */
2707−
2708− if ((octet & 0xC0) != 0x80) {
2709− return yaml_parser_set_scanner_error(parser, directive ?
2710− "while parsing a %TAG directive" : "while parsing a tag",
2711− start_mark, "found an incorrect trailing UTF-8 octet");
2712− }
2713− }
2714−
2715− /* Copy the octet and move the pointers. */
2716−
2717− *(string->pointer++) = octet;
2718− SKIP(parser);
2719− SKIP(parser);
2720− SKIP(parser);
2721−
2722− } while (--width);
2723−
2724− return 1;
2725−}
2726−
2727−/*
2728− * Scan a block scalar.
2729− */
2730−
2731−static int
2732−yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token,
2733− int literal)
2734−{
2735− yaml_mark_t start_mark;
2736− yaml_mark_t end_mark;
2737− yaml_string_t string = NULL_STRING;
2738− yaml_string_t leading_break = NULL_STRING;
2739− yaml_string_t trailing_breaks = NULL_STRING;
2740− int chomping = 0;
2741− int increment = 0;
2742− int indent = 0;
2743− int leading_blank = 0;
2744− int trailing_blank = 0;
2745−
2746− if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
2747− if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
2748− if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
2749−
2750− /* Eat the indicator '|' or '>'. */
2751−
2752− start_mark = parser->mark;
2753−
2754− SKIP(parser);
2755−
2756− /* Scan the additional block scalar indicators. */
2757−
2758− if (!CACHE(parser, 1)) goto error;
2759−
2760− /* Check for a chomping indicator. */
2761−
2762− if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-'))
2763− {
2764− /* Set the chomping method and eat the indicator. */
2765−
2766− chomping = CHECK(parser->buffer, '+') ? +1 : -1;
2767−
2768− SKIP(parser);
2769−
2770− /* Check for an indentation indicator. */
2771−
2772− if (!CACHE(parser, 1)) goto error;
2773−
2774− if (IS_DIGIT(parser->buffer))
2775− {
2776− /* Check that the indentation is greater than 0. */
2777−
2778− if (CHECK(parser->buffer, '0')) {
2779− yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2780− start_mark, "found an indentation indicator equal to 0");
2781− goto error;
2782− }
2783−
2784− /* Get the indentation level and eat the indicator. */
2785−
2786− increment = AS_DIGIT(parser->buffer);
2787−
2788− SKIP(parser);
2789− }
2790− }
2791−
2792− /* Do the same as above, but in the opposite order. */
2793−
2794− else if (IS_DIGIT(parser->buffer))
2795− {
2796− if (CHECK(parser->buffer, '0')) {
2797− yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2798− start_mark, "found an indentation indicator equal to 0");
2799− goto error;
2800− }
2801−
2802− increment = AS_DIGIT(parser->buffer);
2803−
2804− SKIP(parser);
2805−
2806− if (!CACHE(parser, 1)) goto error;
2807−
2808− if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) {
2809− chomping = CHECK(parser->buffer, '+') ? +1 : -1;
2810−
2811− SKIP(parser);
2812− }
2813− }
2814−
2815− /* Eat whitespaces and comments to the end of the line. */
2816−
2817− if (!CACHE(parser, 1)) goto error;
2818−
2819− while (IS_BLANK(parser->buffer)) {
2820− SKIP(parser);
2821− if (!CACHE(parser, 1)) goto error;
2822− }
2823−
2824− if (CHECK(parser->buffer, '#')) {
2825− while (!IS_BREAKZ(parser->buffer)) {
2826− SKIP(parser);
2827− if (!CACHE(parser, 1)) goto error;
2828− }
2829− }
2830−
2831− /* Check if we are at the end of the line. */
2832−
2833− if (!IS_BREAKZ(parser->buffer)) {
2834− yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2835− start_mark, "did not find expected comment or line break");
2836− goto error;
2837− }
2838−
2839− /* Eat a line break. */
2840−
2841− if (IS_BREAK(parser->buffer)) {
2842− if (!CACHE(parser, 2)) goto error;
2843− SKIP_LINE(parser);
2844− }
2845−
2846− end_mark = parser->mark;
2847−
2848− /* Set the indentation level if it was specified. */
2849−
2850− if (increment) {
2851− indent = parser->indent >= 0 ? parser->indent+increment : increment;
2852− }
2853−
2854− /* Scan the leading line breaks and determine the indentation level if needed. */
2855−
2856− if (!yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks,
2857− start_mark, &end_mark)) goto error;
2858−
2859− /* Scan the block scalar content. */
2860−
2861− if (!CACHE(parser, 1)) goto error;
2862−
2863− while ((int)parser->mark.column == indent && !IS_Z(parser->buffer))
2864− {
2865− /*
2866− * We are at the beginning of a non-empty line.
2867− */
2868−
2869− /* Is it a trailing whitespace? */
2870−
2871− trailing_blank = IS_BLANK(parser->buffer);
2872−
2873− /* Check if we need to fold the leading line break. */
2874−
2875− if (!literal && (*leading_break.start == '\n')
2876− && !leading_blank && !trailing_blank)
2877− {
2878− /* Do we need to join the lines by space? */
2879−
2880− if (*trailing_breaks.start == '\0') {
2881− if (!STRING_EXTEND(parser, string)) goto error;
2882− *(string.pointer ++) = ' ';
2883− }
2884−
2885− CLEAR(parser, leading_break);
2886− }
2887− else {
2888− if (!JOIN(parser, string, leading_break)) goto error;
2889− CLEAR(parser, leading_break);
2890− }
2891−
2892− /* Append the remaining line breaks. */
2893−
2894− if (!JOIN(parser, string, trailing_breaks)) goto error;
2895− CLEAR(parser, trailing_breaks);
2896−
2897− /* Is it a leading whitespace? */
2898−
2899− leading_blank = IS_BLANK(parser->buffer);
2900−
2901− /* Consume the current line. */
2902−
2903− while (!IS_BREAKZ(parser->buffer)) {
2904− if (!READ(parser, string)) goto error;
2905− if (!CACHE(parser, 1)) goto error;
2906− }
2907−
2908− /* Consume the line break. */
2909−
2910− if (!CACHE(parser, 2)) goto error;
2911−
2912− if (!READ_LINE(parser, leading_break)) goto error;
2913−
2914− /* Eat the following indentation spaces and line breaks. */
2915−
2916− if (!yaml_parser_scan_block_scalar_breaks(parser,
2917− &indent, &trailing_breaks, start_mark, &end_mark)) goto error;
2918− }
2919−
2920− /* Chomp the tail. */
2921−
2922− if (chomping != -1) {
2923− if (!JOIN(parser, string, leading_break)) goto error;
2924− }
2925− if (chomping == 1) {
2926− if (!JOIN(parser, string, trailing_breaks)) goto error;
2927− }
2928−
2929− /* Create a token. */
2930−
2931− SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
2932− literal ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE,
2933− start_mark, end_mark);
2934−
2935− STRING_DEL(parser, leading_break);
2936− STRING_DEL(parser, trailing_breaks);
2937−
2938− return 1;
2939−
2940−error:
2941− STRING_DEL(parser, string);
2942− STRING_DEL(parser, leading_break);
2943− STRING_DEL(parser, trailing_breaks);
2944−
2945− return 0;
2946−}
2947−
2948−/*
2949− * Scan indentation spaces and line breaks for a block scalar. Determine the
2950− * indentation level if needed.
2951− */
2952−
2953−static int
2954−yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser,
2955− int *indent, yaml_string_t *breaks,
2956− yaml_mark_t start_mark, yaml_mark_t *end_mark)
2957−{
2958− int max_indent = 0;
2959−
2960− *end_mark = parser->mark;
2961−
2962− /* Eat the indentation spaces and line breaks. */
2963−
2964− while (1)
2965− {
2966− /* Eat the indentation spaces. */
2967−
2968− if (!CACHE(parser, 1)) return 0;
2969−
2970− while ((!*indent || (int)parser->mark.column < *indent)
2971− && IS_SPACE(parser->buffer)) {
2972− SKIP(parser);
2973− if (!CACHE(parser, 1)) return 0;
2974− }
2975−
2976− if ((int)parser->mark.column > max_indent)
2977− max_indent = (int)parser->mark.column;
2978−
2979− /* Check for a tab character messing the indentation. */
2980−
2981− if ((!*indent || (int)parser->mark.column < *indent)
2982− && IS_TAB(parser->buffer)) {
2983− return yaml_parser_set_scanner_error(parser, "while scanning a block scalar",
2984− start_mark, "found a tab character where an indentation space is expected");
2985− }
2986−
2987− /* Have we found a non-empty line? */
2988−
2989− if (!IS_BREAK(parser->buffer)) break;
2990−
2991− /* Consume the line break. */
2992−
2993− if (!CACHE(parser, 2)) return 0;
2994− if (!READ_LINE(parser, *breaks)) return 0;
2995− *end_mark = parser->mark;
2996− }
2997−
2998− /* Determine the indentation level if needed. */
2999−
3000− if (!*indent) {
3001− *indent = max_indent;
3002− if (*indent < parser->indent + 1)
3003− *indent = parser->indent + 1;
3004− if (*indent < 1)
3005− *indent = 1;
3006− }
3007−
3008− return 1;
3009−}
3010−
3011−/*
3012− * Scan a quoted scalar.
3013− */
3014−
3015−static int
3016−yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
3017− int single)
3018−{
3019− yaml_mark_t start_mark;
3020− yaml_mark_t end_mark;
3021− yaml_string_t string = NULL_STRING;
3022− yaml_string_t leading_break = NULL_STRING;
3023− yaml_string_t trailing_breaks = NULL_STRING;
3024− yaml_string_t whitespaces = NULL_STRING;
3025− int leading_blanks;
3026−
3027− if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
3028− if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
3029− if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
3030− if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
3031−
3032− /* Eat the left quote. */
3033−
3034− start_mark = parser->mark;
3035−
3036− SKIP(parser);
3037−
3038− /* Consume the content of the quoted scalar. */
3039−
3040− while (1)
3041− {
3042− /* Check that there are no document indicators at the beginning of the line. */
3043−
3044− if (!CACHE(parser, 4)) goto error;
3045−
3046− if (parser->mark.column == 0 &&
3047− ((CHECK_AT(parser->buffer, '-', 0) &&
3048− CHECK_AT(parser->buffer, '-', 1) &&
3049− CHECK_AT(parser->buffer, '-', 2)) ||
3050− (CHECK_AT(parser->buffer, '.', 0) &&
3051− CHECK_AT(parser->buffer, '.', 1) &&
3052− CHECK_AT(parser->buffer, '.', 2))) &&
3053− IS_BLANKZ_AT(parser->buffer, 3))
3054− {
3055− yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
3056− start_mark, "found unexpected document indicator");
3057− goto error;
3058− }
3059−
3060− /* Check for EOF. */
3061−
3062− if (IS_Z(parser->buffer)) {
3063− yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar",
3064− start_mark, "found unexpected end of stream");
3065− goto error;
3066− }
3067−
3068− /* Consume non-blank characters. */
3069−
3070− if (!CACHE(parser, 2)) goto error;
3071−
3072− leading_blanks = 0;
3073−
3074− while (!IS_BLANKZ(parser->buffer))
3075− {
3076− /* Check for an escaped single quote. */
3077−
3078− if (single && CHECK_AT(parser->buffer, '\'', 0)
3079− && CHECK_AT(parser->buffer, '\'', 1))
3080− {
3081− if (!STRING_EXTEND(parser, string)) goto error;
3082− *(string.pointer++) = '\'';
3083− SKIP(parser);
3084− SKIP(parser);
3085− }
3086−
3087− /* Check for the right quote. */
3088−
3089− else if (CHECK(parser->buffer, single ? '\'' : '"'))
3090− {
3091− break;
3092− }
3093−
3094− /* Check for an escaped line break. */
3095−
3096− else if (!single && CHECK(parser->buffer, '\\')
3097− && IS_BREAK_AT(parser->buffer, 1))
3098− {
3099− if (!CACHE(parser, 3)) goto error;
3100− SKIP(parser);
3101− SKIP_LINE(parser);
3102− leading_blanks = 1;
3103− break;
3104− }
3105−
3106− /* Check for an escape sequence. */
3107−
3108− else if (!single && CHECK(parser->buffer, '\\'))
3109− {
3110− size_t code_length = 0;
3111−
3112− if (!STRING_EXTEND(parser, string)) goto error;
3113−
3114− /* Check the escape character. */
3115−
3116− switch (parser->buffer.pointer[1])
3117− {
3118− case '0':
3119− *(string.pointer++) = '\0';
3120− break;
3121−
3122− case 'a':
3123− *(string.pointer++) = '\x07';
3124− break;
3125−
3126− case 'b':
3127− *(string.pointer++) = '\x08';
3128− break;
3129−
3130− case 't':
3131− case '\t':
3132− *(string.pointer++) = '\x09';
3133− break;
3134−
3135− case 'n':
3136− *(string.pointer++) = '\x0A';
3137− break;
3138−
3139− case 'v':
3140− *(string.pointer++) = '\x0B';
3141− break;
3142−
3143− case 'f':
3144− *(string.pointer++) = '\x0C';
3145− break;
3146−
3147− case 'r':
3148− *(string.pointer++) = '\x0D';
3149− break;
3150−
3151− case 'e':
3152− *(string.pointer++) = '\x1B';
3153− break;
3154−
3155− case ' ':
3156− *(string.pointer++) = '\x20';
3157− break;
3158−
3159− case '"':
3160− *(string.pointer++) = '"';
3161− break;
3162−
3163− case '/':
3164− *(string.pointer++) = '/';
3165− break;
3166−
3167− case '\\':
3168− *(string.pointer++) = '\\';
3169− break;
3170−
3171− case 'N': /* NEL (#x85) */
3172− *(string.pointer++) = '\xC2';
3173− *(string.pointer++) = '\x85';
3174− break;
3175−
3176− case '_': /* #xA0 */
3177− *(string.pointer++) = '\xC2';
3178− *(string.pointer++) = '\xA0';
3179− break;
3180−
3181− case 'L': /* LS (#x2028) */
3182− *(string.pointer++) = '\xE2';
3183− *(string.pointer++) = '\x80';
3184− *(string.pointer++) = '\xA8';
3185− break;
3186−
3187− case 'P': /* PS (#x2029) */
3188− *(string.pointer++) = '\xE2';
3189− *(string.pointer++) = '\x80';
3190− *(string.pointer++) = '\xA9';
3191− break;
3192−
3193− case 'x':
3194− code_length = 2;
3195− break;
3196−
3197− case 'u':
3198− code_length = 4;
3199− break;
3200−
3201− case 'U':
3202− code_length = 8;
3203− break;
3204−
3205− default:
3206− yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
3207− start_mark, "found unknown escape character");
3208− goto error;
3209− }
3210−
3211− SKIP(parser);
3212− SKIP(parser);
3213−
3214− /* Consume an arbitrary escape code. */
3215−
3216− if (code_length)
3217− {
3218− unsigned int value = 0;
3219− size_t k;
3220−
3221− /* Scan the character value. */
3222−
3223− if (!CACHE(parser, code_length)) goto error;
3224−
3225− for (k = 0; k < code_length; k ++) {
3226− if (!IS_HEX_AT(parser->buffer, k)) {
3227− yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
3228− start_mark, "did not find expected hexdecimal number");
3229− goto error;
3230− }
3231− value = (value << 4) + AS_HEX_AT(parser->buffer, k);
3232− }
3233−
3234− /* Check the value and write the character. */
3235−
3236− if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
3237− yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar",
3238− start_mark, "found invalid Unicode character escape code");
3239− goto error;
3240− }
3241−
3242− if (value <= 0x7F) {
3243− *(string.pointer++) = value;
3244− }
3245− else if (value <= 0x7FF) {
3246− *(string.pointer++) = 0xC0 + (value >> 6);
3247− *(string.pointer++) = 0x80 + (value & 0x3F);
3248− }
3249− else if (value <= 0xFFFF) {
3250− *(string.pointer++) = 0xE0 + (value >> 12);
3251− *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F);
3252− *(string.pointer++) = 0x80 + (value & 0x3F);
3253− }
3254− else {
3255− *(string.pointer++) = 0xF0 + (value >> 18);
3256− *(string.pointer++) = 0x80 + ((value >> 12) & 0x3F);
3257− *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F);
3258− *(string.pointer++) = 0x80 + (value & 0x3F);
3259− }
3260−
3261− /* Advance the pointer. */
3262−
3263− for (k = 0; k < code_length; k ++) {
3264− SKIP(parser);
3265− }
3266− }
3267− }
3268−
3269− else
3270− {
3271− /* It is a non-escaped non-blank character. */
3272−
3273− if (!READ(parser, string)) goto error;
3274− }
3275−
3276− if (!CACHE(parser, 2)) goto error;
3277− }
3278−
3279− /* Check if we are at the end of the scalar. */
3280−
3281− /* Fix for crash unitialized value crash
3282− * Credit for the bug and input is to OSS Fuzz
3283− * Credit for the fix to Alex Gaynor
3284− */
3285− if (!CACHE(parser, 1)) goto error;
3286− if (CHECK(parser->buffer, single ? '\'' : '"'))
3287− break;
3288−
3289− /* Consume blank characters. */
3290−
3291− if (!CACHE(parser, 1)) goto error;
3292−
3293− while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))
3294− {
3295− if (IS_BLANK(parser->buffer))
3296− {
3297− /* Consume a space or a tab character. */
3298−
3299− if (!leading_blanks) {
3300− if (!READ(parser, whitespaces)) goto error;
3301− }
3302− else {
3303− SKIP(parser);
3304− }
3305− }
3306− else
3307− {
3308− if (!CACHE(parser, 2)) goto error;
3309−
3310− /* Check if it is a first line break. */
3311−
3312− if (!leading_blanks)
3313− {
3314− CLEAR(parser, whitespaces);
3315− if (!READ_LINE(parser, leading_break)) goto error;
3316− leading_blanks = 1;
3317− }
3318− else
3319− {
3320− if (!READ_LINE(parser, trailing_breaks)) goto error;
3321− }
3322− }
3323− if (!CACHE(parser, 1)) goto error;
3324− }
3325−
3326− /* Join the whitespaces or fold line breaks. */
3327−
3328− if (leading_blanks)
3329− {
3330− /* Do we need to fold line breaks? */
3331−
3332− if (leading_break.start[0] == '\n') {
3333− if (trailing_breaks.start[0] == '\0') {
3334− if (!STRING_EXTEND(parser, string)) goto error;
3335− *(string.pointer++) = ' ';
3336− }
3337− else {
3338− if (!JOIN(parser, string, trailing_breaks)) goto error;
3339− CLEAR(parser, trailing_breaks);
3340− }
3341− CLEAR(parser, leading_break);
3342− }
3343− else {
3344− if (!JOIN(parser, string, leading_break)) goto error;
3345− if (!JOIN(parser, string, trailing_breaks)) goto error;
3346− CLEAR(parser, leading_break);
3347− CLEAR(parser, trailing_breaks);
3348− }
3349− }
3350− else
3351− {
3352− if (!JOIN(parser, string, whitespaces)) goto error;
3353− CLEAR(parser, whitespaces);
3354− }
3355− }
3356−
3357− /* Eat the right quote. */
3358−
3359− SKIP(parser);
3360−
3361− end_mark = parser->mark;
3362−
3363− /* Create a token. */
3364−
3365− SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
3366− single ? YAML_SINGLE_QUOTED_SCALAR_STYLE : YAML_DOUBLE_QUOTED_SCALAR_STYLE,
3367− start_mark, end_mark);
3368−
3369− STRING_DEL(parser, leading_break);
3370− STRING_DEL(parser, trailing_breaks);
3371− STRING_DEL(parser, whitespaces);
3372−
3373− return 1;
3374−
3375−error:
3376− STRING_DEL(parser, string);
3377− STRING_DEL(parser, leading_break);
3378− STRING_DEL(parser, trailing_breaks);
3379− STRING_DEL(parser, whitespaces);
3380−
3381− return 0;
3382−}
3383−
3384−/*
3385− * Scan a plain scalar.
3386− */
3387−
3388−static int
3389−yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token)
3390−{
3391− yaml_mark_t start_mark;
3392− yaml_mark_t end_mark;
3393− yaml_string_t string = NULL_STRING;
3394− yaml_string_t leading_break = NULL_STRING;
3395− yaml_string_t trailing_breaks = NULL_STRING;
3396− yaml_string_t whitespaces = NULL_STRING;
3397− int leading_blanks = 0;
3398− int indent = parser->indent+1;
3399−
3400− if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error;
3401− if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error;
3402− if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error;
3403− if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error;
3404−
3405− start_mark = end_mark = parser->mark;
3406−
3407− /* Consume the content of the plain scalar. */
3408−
3409− while (1)
3410− {
3411− /* Check for a document indicator. */
3412−
3413− if (!CACHE(parser, 4)) goto error;
3414−
3415− if (parser->mark.column == 0 &&
3416− ((CHECK_AT(parser->buffer, '-', 0) &&
3417− CHECK_AT(parser->buffer, '-', 1) &&
3418− CHECK_AT(parser->buffer, '-', 2)) ||
3419− (CHECK_AT(parser->buffer, '.', 0) &&
3420− CHECK_AT(parser->buffer, '.', 1) &&
3421− CHECK_AT(parser->buffer, '.', 2))) &&
3422− IS_BLANKZ_AT(parser->buffer, 3)) break;
3423−
3424− /* Check for a comment. */
3425−
3426− if (CHECK(parser->buffer, '#'))
3427− break;
3428−
3429− /* Consume non-blank characters. */
3430−
3431− while (!IS_BLANKZ(parser->buffer))
3432− {
3433− /* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */
3434−
3435− if (parser->flow_level
3436− && CHECK(parser->buffer, ':')
3437− && !IS_BLANKZ_AT(parser->buffer, 1)) {
3438− yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
3439− start_mark, "found unexpected ':'");
3440− goto error;
3441− }
3442−
3443− /* Check for indicators that may end a plain scalar. */
3444−
3445− if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1))
3446− || (parser->flow_level &&
3447− (CHECK(parser->buffer, ',') || CHECK(parser->buffer, ':')
3448− || CHECK(parser->buffer, '?') || CHECK(parser->buffer, '[')
3449− || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{')
3450− || CHECK(parser->buffer, '}'))))
3451− break;
3452−
3453− /* Check if we need to join whitespaces and breaks. */
3454−
3455− if (leading_blanks || whitespaces.start != whitespaces.pointer)
3456− {
3457− if (leading_blanks)
3458− {
3459− /* Do we need to fold line breaks? */
3460−
3461− if (leading_break.start[0] == '\n') {
3462− if (trailing_breaks.start[0] == '\0') {
3463− if (!STRING_EXTEND(parser, string)) goto error;
3464− *(string.pointer++) = ' ';
3465− }
3466− else {
3467− if (!JOIN(parser, string, trailing_breaks)) goto error;
3468− CLEAR(parser, trailing_breaks);
3469− }
3470− CLEAR(parser, leading_break);
3471− }
3472− else {
3473− if (!JOIN(parser, string, leading_break)) goto error;
3474− if (!JOIN(parser, string, trailing_breaks)) goto error;
3475− CLEAR(parser, leading_break);
3476− CLEAR(parser, trailing_breaks);
3477− }
3478−
3479− leading_blanks = 0;
3480− }
3481− else
3482− {
3483− if (!JOIN(parser, string, whitespaces)) goto error;
3484− CLEAR(parser, whitespaces);
3485− }
3486− }
3487−
3488− /* Copy the character. */
3489−
3490− if (!READ(parser, string)) goto error;
3491−
3492− end_mark = parser->mark;
3493−
3494− if (!CACHE(parser, 2)) goto error;
3495− }
3496−
3497− /* Is it the end? */
3498−
3499− if (!(IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)))
3500− break;
3501−
3502− /* Consume blank characters. */
3503−
3504− if (!CACHE(parser, 1)) goto error;
3505−
3506− while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))
3507− {
3508− if (IS_BLANK(parser->buffer))
3509− {
3510− /* Check for tab character that abuse indentation. */
3511−
3512− if (leading_blanks && (int)parser->mark.column < indent
3513− && IS_TAB(parser->buffer)) {
3514− yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
3515− start_mark, "found a tab character that violate indentation");
3516− goto error;
3517− }
3518−
3519− /* Consume a space or a tab character. */
3520−
3521− if (!leading_blanks) {
3522− if (!READ(parser, whitespaces)) goto error;
3523− }
3524− else {
3525− SKIP(parser);
3526− }
3527− }
3528− else
3529− {
3530− if (!CACHE(parser, 2)) goto error;
3531−
3532− /* Check if it is a first line break. */
3533−
3534− if (!leading_blanks)
3535− {
3536− CLEAR(parser, whitespaces);
3537− if (!READ_LINE(parser, leading_break)) goto error;
3538− leading_blanks = 1;
3539− }
3540− else
3541− {
3542− if (!READ_LINE(parser, trailing_breaks)) goto error;
3543− }
3544− }
3545− if (!CACHE(parser, 1)) goto error;
3546− }
3547−
3548− /* Check indentation level. */
3549−
3550− if (!parser->flow_level && (int)parser->mark.column < indent)
3551− break;
3552− }
3553−
3554− /* Create a token. */
3555−
3556− SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start,
3557− YAML_PLAIN_SCALAR_STYLE, start_mark, end_mark);
3558−
3559− /* Note that we change the 'simple_key_allowed' flag. */
3560−
3561− if (leading_blanks) {
3562− parser->simple_key_allowed = 1;
3563− }
3564−
3565− STRING_DEL(parser, leading_break);
3566− STRING_DEL(parser, trailing_breaks);
3567− STRING_DEL(parser, whitespaces);
3568−
3569− return 1;
3570−
3571−error:
3572− STRING_DEL(parser, string);
3573− STRING_DEL(parser, leading_break);
3574− STRING_DEL(parser, trailing_breaks);
3575− STRING_DEL(parser, whitespaces);
3576−
3577− return 0;
3578−}
src/Text/Libyaml.hs → libyaml/src/Text/Libyaml.hsrenamed+104−19
@@ -7,6 +7,7 @@
7{-# LANGUAGE RankNTypes #-}
7{-# LANGUAGE RankNTypes #-}
8{-# LANGUAGE CPP #-}
8{-# LANGUAGE CPP #-}
9{-# LANGUAGE TypeFamilies #-}
9{-# LANGUAGE TypeFamilies #-}
10+{-# LANGUAGE ScopedTypeVariables #-}
10
11
11-- | Low-level, streaming YAML interface. For a higher-level interface, see
12-- | Low-level, streaming YAML interface. For a higher-level interface, see
12-- "Data.Yaml".
13-- "Data.Yaml".
@@ -32,6 +33,11 @@ module Text.Libyaml
32 , FormatOptions
33 , FormatOptions
33 , defaultFormatOptions
34 , defaultFormatOptions
34 , setWidth
35 , setWidth
36+ , setTagRendering
37+ , renderScalarTags
38+ , renderAllTags
39+ , renderNoTags
40+ , renderUriTags
35 -- * Error handling
41 -- * Error handling
36 , YamlException (..)
42 , YamlException (..)
37 , YamlMark (..)
43 , YamlMark (..)
@@ -64,6 +70,11 @@ import qualified Data.ByteString.Char8 as B8
64import qualified Data.ByteString.Internal as B
70import qualified Data.ByteString.Internal as B
65import qualified Data.ByteString.Unsafe as BU
71import qualified Data.ByteString.Unsafe as BU
66
72
73+#if WINDOWS && __GLASGOW_HASKELL__ >= 806
74+import System.Directory (removeFile)
75+import qualified Control.Exception
76+#endif
77+
67data Event =
78data Event =
68 EventStreamStart
79 EventStreamStart
69 | EventStreamEnd
80 | EventStreamEnd
@@ -121,6 +132,11 @@ data Tag = StrTag
121 | NoTag
132 | NoTag
122 deriving (Show, Eq, Read, Data, Typeable)
133 deriving (Show, Eq, Read, Data, Typeable)
123
134
135+tagSuppressed :: Tag -> Bool
136+tagSuppressed (NoTag) = True
137+tagSuppressed (UriTag "") = True
138+tagSuppressed _ = False
139+
124type AnchorName = String
140type AnchorName = String
125type Anchor = Maybe AnchorName
141type Anchor = Maybe AnchorName
126
142
@@ -209,10 +225,10 @@ foreign import ccall unsafe "fdopen"
209 -> IO File
225 -> IO File
210foreign import ccall unsafe "fclose"
226foreign import ccall unsafe "fclose"
211 c_fclose :: File
227 c_fclose :: File
212− -> IO ()
228+ -> IO CInt
213
229
214foreign import ccall unsafe "fclose_helper"
230foreign import ccall unsafe "fclose_helper"
215− c_fclose_helper :: File -> IO ()
231+ c_fclose_helper :: File -> IO CInt
216
232
217foreign import ccall unsafe "yaml_parser_parse"
233foreign import ccall unsafe "yaml_parser_parse"
218 c_yaml_parser_parse :: Parser -> EventRaw -> IO CInt
234 c_yaml_parser_parse :: Parser -> EventRaw -> IO CInt
@@ -446,8 +462,8 @@ foreign import ccall unsafe "yaml_alias_event_initialize"
446 -> Ptr CUChar
462 -> Ptr CUChar
447 -> IO CInt
463 -> IO CInt
448
464
449−toEventRaw :: Event -> (EventRaw -> IO a) -> IO a
465+toEventRaw :: FormatOptions -> Event -> (EventRaw -> IO a) -> IO a
450−toEventRaw e f = allocaBytes eventSize $ \er -> do
466+toEventRaw opts e f = allocaBytes eventSize $ \er -> do
451 ret <- case e of
467 ret <- case e of
452 EventStreamStart ->
468 EventStreamStart ->
453 c_yaml_stream_start_event_initialize
469 c_yaml_stream_start_event_initialize
@@ -465,13 +481,13 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
465 len' = fromIntegral len :: CInt
481 len' = fromIntegral len :: CInt
466 let thetag' = tagToString thetag
482 let thetag' = tagToString thetag
467 withCString thetag' $ \tag' -> do
483 withCString thetag' $ \tag' -> do
484+ let pi0 = tagsImplicit e
468− let (pi, style) =
485+ (pi, style) =
469− case style0 of
486+ case style0 of
470− PlainNoTag -> (1, Plain)
487+ PlainNoTag -> (1, Plain)
471− x -> (0, x)
488+ x -> (pi0, x)
472 style' = toEnum $ fromEnum style
489 style' = toEnum $ fromEnum style
473 tagP = castPtr tag'
490 tagP = castPtr tag'
474− qi = if null thetag' then 1 else 0
475 case anchor of
491 case anchor of
476 Nothing ->
492 Nothing ->
477 c_yaml_scalar_event_initialize
493 c_yaml_scalar_event_initialize
@@ -481,7 +497,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
481 value' -- value
497 value' -- value
482 len' -- length
498 len' -- length
483 pi -- plain_implicit
499 pi -- plain_implicit
484− qi -- quoted_implicit
500+ pi -- quoted_implicit
485 style' -- style
501 style' -- style
486 Just anchor' ->
502 Just anchor' ->
487 withCString anchor' $ \anchorP' -> do
503 withCString anchor' $ \anchorP' -> do
@@ -493,7 +509,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
493 value' -- value
509 value' -- value
494 len' -- length
510 len' -- length
495 0 -- plain_implicit
511 0 -- plain_implicit
496− qi -- quoted_implicit
512+ pi -- quoted_implicit
497 style' -- style
513 style' -- style
498 EventSequenceStart tag style Nothing ->
514 EventSequenceStart tag style Nothing ->
499 withCString (tagToString tag) $ \tag' -> do
515 withCString (tagToString tag) $ \tag' -> do
@@ -502,7 +518,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
502 er
518 er
503 nullPtr
519 nullPtr
504 tagP
520 tagP
505− 1
521+ (tagsImplicit e)
506 (toEnum $ fromEnum style)
522 (toEnum $ fromEnum style)
507 EventSequenceStart tag style (Just anchor) ->
523 EventSequenceStart tag style (Just anchor) ->
508 withCString (tagToString tag) $ \tag' -> do
524 withCString (tagToString tag) $ \tag' -> do
@@ -513,7 +529,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
513 er
529 er
514 anchorP
530 anchorP
515 tagP
531 tagP
516− 1
532+ (tagsImplicit e)
517 (toEnum $ fromEnum style)
533 (toEnum $ fromEnum style)
518 EventSequenceEnd ->
534 EventSequenceEnd ->
519 c_yaml_sequence_end_event_initialize er
535 c_yaml_sequence_end_event_initialize er
@@ -524,7 +540,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
524 er
540 er
525 nullPtr
541 nullPtr
526 tagP
542 tagP
527− 1
543+ (tagsImplicit e)
528 (toEnum $ fromEnum style)
544 (toEnum $ fromEnum style)
529 EventMappingStart tag style (Just anchor) ->
545 EventMappingStart tag style (Just anchor) ->
530 withCString (tagToString tag) $ \tag' -> do
546 withCString (tagToString tag) $ \tag' -> do
@@ -535,7 +551,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
535 er
551 er
536 anchorP
552 anchorP
537 tagP
553 tagP
538− 1
554+ (tagsImplicit e)
539 (toEnum $ fromEnum style)
555 (toEnum $ fromEnum style)
540 EventMappingEnd ->
556 EventMappingEnd ->
541 c_yaml_mapping_end_event_initialize er
557 c_yaml_mapping_end_event_initialize er
@@ -547,6 +563,11 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
547 anchorP
563 anchorP
548 unless (ret == 1) $ throwIO $ ToEventRawException ret
564 unless (ret == 1) $ throwIO $ ToEventRawException ret
549 f er
565 f er
566+ where
567+ tagsImplicit (EventScalar _ t _ _) | tagSuppressed t = 1
568+ tagsImplicit (EventMappingStart t _ _) | tagSuppressed t = 1
569+ tagsImplicit (EventSequenceStart t _ _) | tagSuppressed t = 1
570+ tagsImplicit evt = toImplicitParam $ formatOptionsRenderTags opts evt
550
571
551newtype ToEventRawException = ToEventRawException CInt
572newtype ToEventRawException = ToEventRawException CInt
552 deriving (Show, Typeable)
573 deriving (Show, Typeable)
@@ -638,7 +659,8 @@ decodeFileMarked file =
638 c_yaml_parser_set_input_file ptr file'
659 c_yaml_parser_set_input_file ptr file'
639 return (ptr, file')
660 return (ptr, file')
640 cleanup (ptr, file') = do
661 cleanup (ptr, file') = do
641− c_fclose_helper file'
662+ res <- c_fclose_helper file'
663+ when (res /= 0) $ throwIO $ YamlException $ "could not close file: " ++ file
642 c_yaml_parser_delete ptr
664 c_yaml_parser_delete ptr
643 free ptr
665 free ptr
644
666
@@ -663,11 +685,58 @@ parserParseOne' parser = allocaBytes eventSize $ \er -> do
663 return $ Left $ YamlParseException problem context problemMark
685 return $ Left $ YamlParseException problem context problemMark
664 else Right <$> getEvent er
686 else Right <$> getEvent er
665
687
688+-- | Whether a tag should be rendered explicitly in the output or left
689+-- implicit.
690+--
691+-- @since 0.1.1.0
692+data TagRender = Explicit | Implicit
693+ deriving (Enum)
694+
695+toImplicitParam :: TagRender -> CInt
696+toImplicitParam Explicit = 0
697+toImplicitParam Implicit = 1
698+
699+-- | A value for 'formatOptionsRenderTags' that renders no
700+-- collection tags but all scalar tags (unless suppressed with styles
701+-- 'NoTag or 'PlainNoTag').
702+--
703+-- @since 0.1.1.0
704+renderScalarTags :: Event -> TagRender
705+renderScalarTags (EventScalar _ _ _ _) = Explicit
706+renderScalarTags (EventSequenceStart _ _ _) = Implicit
707+renderScalarTags (EventMappingStart _ _ _) = Implicit
708+renderScalarTags _ = Implicit
709+
710+-- | A value for 'formatOptionsRenderTags' that renders all
711+-- tags (except 'NoTag' tag and 'PlainNoTag' style).
712+--
713+-- @since 0.1.1.0
714+renderAllTags :: Event -> TagRender
715+renderAllTags _ = Explicit
716+
717+-- | A value for 'formatOptionsRenderTags' that renders no
718+-- tags.
719+--
720+-- @since 0.1.1.0
721+renderNoTags :: Event -> TagRender
722+renderNoTags _ = Implicit
723+
724+-- | A value for 'formatOptionsRenderCollectionTags' that renders tags
725+-- which are instances of 'UriTag'
726+--
727+-- @since 0.1.1.0
728+renderUriTags :: Event -> TagRender
729+renderUriTags (EventScalar _ UriTag{} _ _) = Explicit
730+renderUriTags (EventSequenceStart UriTag{} _ _) = Explicit
731+renderUriTags (EventMappingStart UriTag{} _ _) = Explicit
732+renderUriTags _ = Implicit
733+
666-- | Contains options relating to the formatting (indendation, width) of the YAML output.
734-- | Contains options relating to the formatting (indendation, width) of the YAML output.
667--
735--
668-- @since 0.10.2.0
736-- @since 0.10.2.0
669data FormatOptions = FormatOptions
737data FormatOptions = FormatOptions
670 { formatOptionsWidth :: Maybe Int
738 { formatOptionsWidth :: Maybe Int
739+ , formatOptionsRenderTags :: Event -> TagRender
671 }
740 }
672
741
673-- |
742-- |
@@ -675,6 +744,7 @@ data FormatOptions = FormatOptions
675defaultFormatOptions :: FormatOptions
744defaultFormatOptions :: FormatOptions
676defaultFormatOptions = FormatOptions
745defaultFormatOptions = FormatOptions
677 { formatOptionsWidth = Just 80 -- by default the width is set to 0 in the C code, which gets turned into 80 in yaml_emitter_emit_stream_start
746 { formatOptionsWidth = Just 80 -- by default the width is set to 0 in the C code, which gets turned into 80 in yaml_emitter_emit_stream_start
747+ , formatOptionsRenderTags = renderScalarTags
678 }
748 }
679
749
680-- | Set the maximum number of columns in the YAML output, or 'Nothing' for infinite. By default, the limit is 80 characters.
750-- | Set the maximum number of columns in the YAML output, or 'Nothing' for infinite. By default, the limit is 80 characters.
@@ -683,6 +753,12 @@ defaultFormatOptions = FormatOptions
683setWidth :: Maybe Int -> FormatOptions -> FormatOptions
753setWidth :: Maybe Int -> FormatOptions -> FormatOptions
684setWidth w opts = opts { formatOptionsWidth = w }
754setWidth w opts = opts { formatOptionsWidth = w }
685
755
756+-- | Control when and whether tags are rendered to output.
757+--
758+-- @since 0.1.1.0
759+setTagRendering :: (Event -> TagRender) -> FormatOptions -> FormatOptions
760+setTagRendering f opts = opts { formatOptionsRenderTags = f }
761+
686encode :: MonadResource m => ConduitM Event o m ByteString
762encode :: MonadResource m => ConduitM Event o m ByteString
687encode = encodeWith defaultFormatOptions
763encode = encodeWith defaultFormatOptions
688
764
@@ -700,7 +776,7 @@ encodeWith opts =
700 close _ fbuf = withForeignPtr fbuf $ \b -> do
776 close _ fbuf = withForeignPtr fbuf $ \b -> do
701 ptr' <- c_get_buffer_buff b
777 ptr' <- c_get_buffer_buff b
702 len <- c_get_buffer_used b
778 len <- c_get_buffer_used b
703− fptr <- newForeignPtr_ $ castPtr ptr'
779+ fptr <- newForeignPtr finalizerFree $ castPtr ptr'
704 return $ B.fromForeignPtr fptr 0 $ fromIntegral len
780 return $ B.fromForeignPtr fptr 0 $ fromIntegral len
705
781
706
782
@@ -716,9 +792,18 @@ encodeFileWith :: MonadResource m
716 -> FilePath
792 -> FilePath
717 -> ConduitM Event o m ()
793 -> ConduitM Event o m ()
718encodeFileWith opts filePath =
794encodeFileWith opts filePath =
719− bracketP getFile c_fclose $ \file -> runEmitter opts (alloc file) (\u _ -> return u)
795+ bracketP getFile cleanup $ \file -> runEmitter opts (alloc file) (\u _ -> return u)
720 where
796 where
797+ cleanup file = do
798+ res <- c_fclose file
799+ when (res /= 0) $ throwIO $ YamlException $ "could not close file: " ++ filePath
800+
721 getFile = do
801 getFile = do
802+#if WINDOWS && __GLASGOW_HASKELL__ >= 806
803+ -- See: https://github.com/snoyberg/yaml/issues/178#issuecomment-550180027
804+ removeFile filePath `Control.Exception.catch`
805+ (\(_ :: Control.Exception.IOException) -> pure ())
806+#endif
722 file <- openFile filePath write_flags "w"
807 file <- openFile filePath write_flags "w"
723 if file == nullPtr
808 if file == nullPtr
724 then throwIO $ YamlException $ "could not open file for write: " ++ filePath
809 then throwIO $ YamlException $ "could not open file for write: " ++ filePath
@@ -756,7 +841,7 @@ runEmitter opts allocI closeI =
756 loop = await >>= maybe (close ()) push
841 loop = await >>= maybe (close ()) push
757
842
758 push e = do
843 push e = do
759− _ <- liftIO $ toEventRaw e $ c_yaml_emitter_emit emitter
844+ _ <- liftIO $ toEventRaw opts e $ c_yaml_emitter_emit emitter
760 loop
845 loop
761 close u = liftIO $ closeI u a
846 close u = liftIO $ closeI u a
762
847
libyaml/writer.cdeleted−141
@@ -1,141 +0,0 @@
1−
2−#include "yaml_private.h"
3−
4−/*
5− * Declarations.
6− */
7−
8−static int
9−yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem);
10−
11−YAML_DECLARE(int)
12−yaml_emitter_flush(yaml_emitter_t *emitter);
13−
14−/*
15− * Set the writer error and return 0.
16− */
17−
18−static int
19−yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem)
20−{
21− emitter->error = YAML_WRITER_ERROR;
22− emitter->problem = problem;
23−
24− return 0;
25−}
26−
27−/*
28− * Flush the output buffer.
29− */
30−
31−YAML_DECLARE(int)
32−yaml_emitter_flush(yaml_emitter_t *emitter)
33−{
34− int low, high;
35−
36− assert(emitter); /* Non-NULL emitter object is expected. */
37− assert(emitter->write_handler); /* Write handler must be set. */
38− assert(emitter->encoding); /* Output encoding must be set. */
39−
40− emitter->buffer.last = emitter->buffer.pointer;
41− emitter->buffer.pointer = emitter->buffer.start;
42−
43− /* Check if the buffer is empty. */
44−
45− if (emitter->buffer.start == emitter->buffer.last) {
46− return 1;
47− }
48−
49− /* If the output encoding is UTF-8, we don't need to recode the buffer. */
50−
51− if (emitter->encoding == YAML_UTF8_ENCODING)
52− {
53− if (emitter->write_handler(emitter->write_handler_data,
54− emitter->buffer.start,
55− emitter->buffer.last - emitter->buffer.start)) {
56− emitter->buffer.last = emitter->buffer.start;
57− emitter->buffer.pointer = emitter->buffer.start;
58− return 1;
59− }
60− else {
61− return yaml_emitter_set_writer_error(emitter, "write error");
62− }
63− }
64−
65− /* Recode the buffer into the raw buffer. */
66−
67− low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
68− high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
69−
70− while (emitter->buffer.pointer != emitter->buffer.last)
71− {
72− unsigned char octet;
73− unsigned int width;
74− unsigned int value;
75− size_t k;
76−
77− /*
78− * See the "reader.c" code for more details on UTF-8 encoding. Note
79− * that we assume that the buffer contains a valid UTF-8 sequence.
80− */
81−
82− /* Read the next UTF-8 character. */
83−
84− octet = emitter->buffer.pointer[0];
85−
86− width = (octet & 0x80) == 0x00 ? 1 :
87− (octet & 0xE0) == 0xC0 ? 2 :
88− (octet & 0xF0) == 0xE0 ? 3 :
89− (octet & 0xF8) == 0xF0 ? 4 : 0;
90−
91− value = (octet & 0x80) == 0x00 ? octet & 0x7F :
92− (octet & 0xE0) == 0xC0 ? octet & 0x1F :
93− (octet & 0xF0) == 0xE0 ? octet & 0x0F :
94− (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
95−
96− for (k = 1; k < width; k ++) {
97− octet = emitter->buffer.pointer[k];
98− value = (value << 6) + (octet & 0x3F);
99− }
100−
101− emitter->buffer.pointer += width;
102−
103− /* Write the character. */
104−
105− if (value < 0x10000)
106− {
107− emitter->raw_buffer.last[high] = value >> 8;
108− emitter->raw_buffer.last[low] = value & 0xFF;
109−
110− emitter->raw_buffer.last += 2;
111− }
112− else
113− {
114− /* Write the character using a surrogate pair (check "reader.c"). */
115−
116− value -= 0x10000;
117− emitter->raw_buffer.last[high] = 0xD8 + (value >> 18);
118− emitter->raw_buffer.last[low] = (value >> 10) & 0xFF;
119− emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF);
120− emitter->raw_buffer.last[low+2] = value & 0xFF;
121−
122− emitter->raw_buffer.last += 4;
123− }
124− }
125−
126− /* Write the raw buffer. */
127−
128− if (emitter->write_handler(emitter->write_handler_data,
129− emitter->raw_buffer.start,
130− emitter->raw_buffer.last - emitter->raw_buffer.start)) {
131− emitter->buffer.last = emitter->buffer.start;
132− emitter->buffer.pointer = emitter->buffer.start;
133− emitter->raw_buffer.last = emitter->raw_buffer.start;
134− emitter->raw_buffer.pointer = emitter->raw_buffer.start;
135− return 1;
136− }
137− else {
138− return yaml_emitter_set_writer_error(emitter, "write error");
139− }
140−}
141−
libyaml/yaml.hdeleted−1973
@@ -1,1973 +0,0 @@
1−/**
2− * @file yaml.h
3− * @brief Public interface for libyaml.
4− *
5− * Include the header file with the code:
6− * @code
7− * #include <yaml.h>
8− * @endcode
9− */
10−
11−#ifndef YAML_H
12−#define YAML_H
13−
14−#ifdef __cplusplus
15−extern "C" {
16−#endif
17−
18−#include <stdlib.h>
19−#include <stdio.h>
20−#include <string.h>
21−
22−/**
23− * @defgroup export Export Definitions
24− * @{
25− */
26−
27−/** The public API declaration. */
28−
29−#if defined(__MINGW32__)
30−# define YAML_DECLARE(type) type
31−#elif defined(WIN32)
32−# if defined(YAML_DECLARE_STATIC)
33−# define YAML_DECLARE(type) type
34−# elif defined(YAML_DECLARE_EXPORT)
35−# define YAML_DECLARE(type) __declspec(dllexport) type
36−# else
37−# define YAML_DECLARE(type) __declspec(dllimport) type
38−# endif
39−#else
40−# define YAML_DECLARE(type) type
41−#endif
42−
43−/** @} */
44−
45−/**
46− * @defgroup version Version Information
47− * @{
48− */
49−
50−/**
51− * Get the library version as a string.
52− *
53− * @returns The function returns the pointer to a static string of the form
54− * @c "X.Y.Z", where @c X is the major version number, @c Y is a minor version
55− * number, and @c Z is the patch version number.
56− */
57−
58−YAML_DECLARE(const char *)
59−yaml_get_version_string(void);
60−
61−/**
62− * Get the library version numbers.
63− *
64− * @param[out] major Major version number.
65− * @param[out] minor Minor version number.
66− * @param[out] patch Patch version number.
67− */
68−
69−YAML_DECLARE(void)
70−yaml_get_version(int *major, int *minor, int *patch);
71−
72−/** @} */
73−
74−/**
75− * @defgroup basic Basic Types
76− * @{
77− */
78−
79−/** The character type (UTF-8 octet). */
80−typedef unsigned char yaml_char_t;
81−
82−/** The version directive data. */
83−typedef struct yaml_version_directive_s {
84− /** The major version number. */
85− int major;
86− /** The minor version number. */
87− int minor;
88−} yaml_version_directive_t;
89−
90−/** The tag directive data. */
91−typedef struct yaml_tag_directive_s {
92− /** The tag handle. */
93− yaml_char_t *handle;
94− /** The tag prefix. */
95− yaml_char_t *prefix;
96−} yaml_tag_directive_t;
97−
98−/** The stream encoding. */
99−typedef enum yaml_encoding_e {
100− /** Let the parser choose the encoding. */
101− YAML_ANY_ENCODING,
102− /** The default UTF-8 encoding. */
103− YAML_UTF8_ENCODING,
104− /** The UTF-16-LE encoding with BOM. */
105− YAML_UTF16LE_ENCODING,
106− /** The UTF-16-BE encoding with BOM. */
107− YAML_UTF16BE_ENCODING
108−} yaml_encoding_t;
109−
110−/** Line break types. */
111−
112−typedef enum yaml_break_e {
113− /** Let the parser choose the break type. */
114− YAML_ANY_BREAK,
115− /** Use CR for line breaks (Mac style). */
116− YAML_CR_BREAK,
117− /** Use LN for line breaks (Unix style). */
118− YAML_LN_BREAK,
119− /** Use CR LN for line breaks (DOS style). */
120− YAML_CRLN_BREAK
121−} yaml_break_t;
122−
123−/** Many bad things could happen with the parser and emitter. */
124−typedef enum yaml_error_type_e {
125− /** No error is produced. */
126− YAML_NO_ERROR,
127−
128− /** Cannot allocate or reallocate a block of memory. */
129− YAML_MEMORY_ERROR,
130−
131− /** Cannot read or decode the input stream. */
132− YAML_READER_ERROR,
133− /** Cannot scan the input stream. */
134− YAML_SCANNER_ERROR,
135− /** Cannot parse the input stream. */
136− YAML_PARSER_ERROR,
137− /** Cannot compose a YAML document. */
138− YAML_COMPOSER_ERROR,
139−
140− /** Cannot write to the output stream. */
141− YAML_WRITER_ERROR,
142− /** Cannot emit a YAML stream. */
143− YAML_EMITTER_ERROR
144−} yaml_error_type_t;
145−
146−/** The pointer position. */
147−typedef struct yaml_mark_s {
148− /** The position index. */
149− size_t index;
150−
151− /** The position line. */
152− size_t line;
153−
154− /** The position column. */
155− size_t column;
156−} yaml_mark_t;
157−
158−/** @} */
159−
160−/**
161− * @defgroup styles Node Styles
162− * @{
163− */
164−
165−/** Scalar styles. */
166−typedef enum yaml_scalar_style_e {
167− /** Let the emitter choose the style. */
168− YAML_ANY_SCALAR_STYLE,
169−
170− /** The plain scalar style. */
171− YAML_PLAIN_SCALAR_STYLE,
172−
173− /** The single-quoted scalar style. */
174− YAML_SINGLE_QUOTED_SCALAR_STYLE,
175− /** The double-quoted scalar style. */
176− YAML_DOUBLE_QUOTED_SCALAR_STYLE,
177−
178− /** The literal scalar style. */
179− YAML_LITERAL_SCALAR_STYLE,
180− /** The folded scalar style. */
181− YAML_FOLDED_SCALAR_STYLE
182−} yaml_scalar_style_t;
183−
184−/** Sequence styles. */
185−typedef enum yaml_sequence_style_e {
186− /** Let the emitter choose the style. */
187− YAML_ANY_SEQUENCE_STYLE,
188−
189− /** The block sequence style. */
190− YAML_BLOCK_SEQUENCE_STYLE,
191− /** The flow sequence style. */
192− YAML_FLOW_SEQUENCE_STYLE
193−} yaml_sequence_style_t;
194−
195−/** Mapping styles. */
196−typedef enum yaml_mapping_style_e {
197− /** Let the emitter choose the style. */
198− YAML_ANY_MAPPING_STYLE,
199−
200− /** The block mapping style. */
201− YAML_BLOCK_MAPPING_STYLE,
202− /** The flow mapping style. */
203− YAML_FLOW_MAPPING_STYLE
204−/* YAML_FLOW_SET_MAPPING_STYLE */
205−} yaml_mapping_style_t;
206−
207−/** @} */
208−
209−/**
210− * @defgroup tokens Tokens
211− * @{
212− */
213−
214−/** Token types. */
215−typedef enum yaml_token_type_e {
216− /** An empty token. */
217− YAML_NO_TOKEN,
218−
219− /** A STREAM-START token. */
220− YAML_STREAM_START_TOKEN,
221− /** A STREAM-END token. */
222− YAML_STREAM_END_TOKEN,
223−
224− /** A VERSION-DIRECTIVE token. */
225− YAML_VERSION_DIRECTIVE_TOKEN,
226− /** A TAG-DIRECTIVE token. */
227− YAML_TAG_DIRECTIVE_TOKEN,
228− /** A DOCUMENT-START token. */
229− YAML_DOCUMENT_START_TOKEN,
230− /** A DOCUMENT-END token. */
231− YAML_DOCUMENT_END_TOKEN,
232−
233− /** A BLOCK-SEQUENCE-START token. */
234− YAML_BLOCK_SEQUENCE_START_TOKEN,
235− /** A BLOCK-SEQUENCE-END token. */
236− YAML_BLOCK_MAPPING_START_TOKEN,
237− /** A BLOCK-END token. */
238− YAML_BLOCK_END_TOKEN,
239−
240− /** A FLOW-SEQUENCE-START token. */
241− YAML_FLOW_SEQUENCE_START_TOKEN,
242− /** A FLOW-SEQUENCE-END token. */
243− YAML_FLOW_SEQUENCE_END_TOKEN,
244− /** A FLOW-MAPPING-START token. */
245− YAML_FLOW_MAPPING_START_TOKEN,
246− /** A FLOW-MAPPING-END token. */
247− YAML_FLOW_MAPPING_END_TOKEN,
248−
249− /** A BLOCK-ENTRY token. */
250− YAML_BLOCK_ENTRY_TOKEN,
251− /** A FLOW-ENTRY token. */
252− YAML_FLOW_ENTRY_TOKEN,
253− /** A KEY token. */
254− YAML_KEY_TOKEN,
255− /** A VALUE token. */
256− YAML_VALUE_TOKEN,
257−
258− /** An ALIAS token. */
259− YAML_ALIAS_TOKEN,
260− /** An ANCHOR token. */
261− YAML_ANCHOR_TOKEN,
262− /** A TAG token. */
263− YAML_TAG_TOKEN,
264− /** A SCALAR token. */
265− YAML_SCALAR_TOKEN
266−} yaml_token_type_t;
267−
268−/** The token structure. */
269−typedef struct yaml_token_s {
270−
271− /** The token type. */
272− yaml_token_type_t type;
273−
274− /** The token data. */
275− union {
276−
277− /** The stream start (for @c YAML_STREAM_START_TOKEN). */
278− struct {
279− /** The stream encoding. */
280− yaml_encoding_t encoding;
281− } stream_start;
282−
283− /** The alias (for @c YAML_ALIAS_TOKEN). */
284− struct {
285− /** The alias value. */
286− yaml_char_t *value;
287− } alias;
288−
289− /** The anchor (for @c YAML_ANCHOR_TOKEN). */
290− struct {
291− /** The anchor value. */
292− yaml_char_t *value;
293− } anchor;
294−
295− /** The tag (for @c YAML_TAG_TOKEN). */
296− struct {
297− /** The tag handle. */
298− yaml_char_t *handle;
299− /** The tag suffix. */
300− yaml_char_t *suffix;
301− } tag;
302−
303− /** The scalar value (for @c YAML_SCALAR_TOKEN). */
304− struct {
305− /** The scalar value. */
306− yaml_char_t *value;
307− /** The length of the scalar value. */
308− size_t length;
309− /** The scalar style. */
310− yaml_scalar_style_t style;
311− } scalar;
312−
313− /** The version directive (for @c YAML_VERSION_DIRECTIVE_TOKEN). */
314− struct {
315− /** The major version number. */
316− int major;
317− /** The minor version number. */
318− int minor;
319− } version_directive;
320−
321− /** The tag directive (for @c YAML_TAG_DIRECTIVE_TOKEN). */
322− struct {
323− /** The tag handle. */
324− yaml_char_t *handle;
325− /** The tag prefix. */
326− yaml_char_t *prefix;
327− } tag_directive;
328−
329− } data;
330−
331− /** The beginning of the token. */
332− yaml_mark_t start_mark;
333− /** The end of the token. */
334− yaml_mark_t end_mark;
335−
336−} yaml_token_t;
337−
338−/**
339− * Free any memory allocated for a token object.
340− *
341− * @param[in,out] token A token object.
342− */
343−
344−YAML_DECLARE(void)
345−yaml_token_delete(yaml_token_t *token);
346−
347−/** @} */
348−
349−/**
350− * @defgroup events Events
351− * @{
352− */
353−
354−/** Event types. */
355−typedef enum yaml_event_type_e {
356− /** An empty event. */
357− YAML_NO_EVENT,
358−
359− /** A STREAM-START event. */
360− YAML_STREAM_START_EVENT,
361− /** A STREAM-END event. */
362− YAML_STREAM_END_EVENT,
363−
364− /** A DOCUMENT-START event. */
365− YAML_DOCUMENT_START_EVENT,
366− /** A DOCUMENT-END event. */
367− YAML_DOCUMENT_END_EVENT,
368−
369− /** An ALIAS event. */
370− YAML_ALIAS_EVENT,
371− /** A SCALAR event. */
372− YAML_SCALAR_EVENT,
373−
374− /** A SEQUENCE-START event. */
375− YAML_SEQUENCE_START_EVENT,
376− /** A SEQUENCE-END event. */
377− YAML_SEQUENCE_END_EVENT,
378−
379− /** A MAPPING-START event. */
380− YAML_MAPPING_START_EVENT,
381− /** A MAPPING-END event. */
382− YAML_MAPPING_END_EVENT
383−} yaml_event_type_t;
384−
385−/** The event structure. */
386−typedef struct yaml_event_s {
387−
388− /** The event type. */
389− yaml_event_type_t type;
390−
391− /** The event data. */
392− union {
393−
394− /** The stream parameters (for @c YAML_STREAM_START_EVENT). */
395− struct {
396− /** The document encoding. */
397− yaml_encoding_t encoding;
398− } stream_start;
399−
400− /** The document parameters (for @c YAML_DOCUMENT_START_EVENT). */
401− struct {
402− /** The version directive. */
403− yaml_version_directive_t *version_directive;
404−
405− /** The list of tag directives. */
406− struct {
407− /** The beginning of the tag directives list. */
408− yaml_tag_directive_t *start;
409− /** The end of the tag directives list. */
410− yaml_tag_directive_t *end;
411− } tag_directives;
412−
413− /** Is the document indicator implicit? */
414− int implicit;
415− } document_start;
416−
417− /** The document end parameters (for @c YAML_DOCUMENT_END_EVENT). */
418− struct {
419− /** Is the document end indicator implicit? */
420− int implicit;
421− } document_end;
422−
423− /** The alias parameters (for @c YAML_ALIAS_EVENT). */
424− struct {
425− /** The anchor. */
426− yaml_char_t *anchor;
427− } alias;
428−
429− /** The scalar parameters (for @c YAML_SCALAR_EVENT). */
430− struct {
431− /** The anchor. */
432− yaml_char_t *anchor;
433− /** The tag. */
434− yaml_char_t *tag;
435− /** The scalar value. */
436− yaml_char_t *value;
437− /** The length of the scalar value. */
438− size_t length;
439− /** Is the tag optional for the plain style? */
440− int plain_implicit;
441− /** Is the tag optional for any non-plain style? */
442− int quoted_implicit;
443− /** The scalar style. */
444− yaml_scalar_style_t style;
445− } scalar;
446−
447− /** The sequence parameters (for @c YAML_SEQUENCE_START_EVENT). */
448− struct {
449− /** The anchor. */
450− yaml_char_t *anchor;
451− /** The tag. */
452− yaml_char_t *tag;
453− /** Is the tag optional? */
454− int implicit;
455− /** The sequence style. */
456− yaml_sequence_style_t style;
457− } sequence_start;
458−
459− /** The mapping parameters (for @c YAML_MAPPING_START_EVENT). */
460− struct {
461− /** The anchor. */
462− yaml_char_t *anchor;
463− /** The tag. */
464− yaml_char_t *tag;
465− /** Is the tag optional? */
466− int implicit;
467− /** The mapping style. */
468− yaml_mapping_style_t style;
469− } mapping_start;
470−
471− } data;
472−
473− /** The beginning of the event. */
474− yaml_mark_t start_mark;
475− /** The end of the event. */
476− yaml_mark_t end_mark;
477−
478−} yaml_event_t;
479−
480−/**
481− * Create the STREAM-START event.
482− *
483− * @param[out] event An empty event object.
484− * @param[in] encoding The stream encoding.
485− *
486− * @returns @c 1 if the function succeeded, @c 0 on error.
487− */
488−
489−YAML_DECLARE(int)
490−yaml_stream_start_event_initialize(yaml_event_t *event,
491− yaml_encoding_t encoding);
492−
493−/**
494− * Create the STREAM-END event.
495− *
496− * @param[out] event An empty event object.
497− *
498− * @returns @c 1 if the function succeeded, @c 0 on error.
499− */
500−
501−YAML_DECLARE(int)
502−yaml_stream_end_event_initialize(yaml_event_t *event);
503−
504−/**
505− * Create the DOCUMENT-START event.
506− *
507− * The @a implicit argument is considered as a stylistic parameter and may be
508− * ignored by the emitter.
509− *
510− * @param[out] event An empty event object.
511− * @param[in] version_directive The %YAML directive value or
512− * @c NULL.
513− * @param[in] tag_directives_start The beginning of the %TAG
514− * directives list.
515− * @param[in] tag_directives_end The end of the %TAG directives
516− * list.
517− * @param[in] implicit If the document start indicator is
518− * implicit.
519− *
520− * @returns @c 1 if the function succeeded, @c 0 on error.
521− */
522−
523−YAML_DECLARE(int)
524−yaml_document_start_event_initialize(yaml_event_t *event,
525− yaml_version_directive_t *version_directive,
526− yaml_tag_directive_t *tag_directives_start,
527− yaml_tag_directive_t *tag_directives_end,
528− int implicit);
529−
530−/**
531− * Create the DOCUMENT-END event.
532− *
533− * The @a implicit argument is considered as a stylistic parameter and may be
534− * ignored by the emitter.
535− *
536− * @param[out] event An empty event object.
537− * @param[in] implicit If the document end indicator is implicit.
538− *
539− * @returns @c 1 if the function succeeded, @c 0 on error.
540− */
541−
542−YAML_DECLARE(int)
543−yaml_document_end_event_initialize(yaml_event_t *event, int implicit);
544−
545−/**
546− * Create an ALIAS event.
547− *
548− * @param[out] event An empty event object.
549− * @param[in] anchor The anchor value.
550− *
551− * @returns @c 1 if the function succeeded, @c 0 on error.
552− */
553−
554−YAML_DECLARE(int)
555−yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor);
556−
557−/**
558− * Create a SCALAR event.
559− *
560− * The @a style argument may be ignored by the emitter.
561− *
562− * Either the @a tag attribute or one of the @a plain_implicit and
563− * @a quoted_implicit flags must be set.
564− *
565− * @param[out] event An empty event object.
566− * @param[in] anchor The scalar anchor or @c NULL.
567− * @param[in] tag The scalar tag or @c NULL.
568− * @param[in] value The scalar value.
569− * @param[in] length The length of the scalar value.
570− * @param[in] plain_implicit If the tag may be omitted for the plain
571− * style.
572− * @param[in] quoted_implicit If the tag may be omitted for any
573− * non-plain style.
574− * @param[in] style The scalar style.
575− *
576− * @returns @c 1 if the function succeeded, @c 0 on error.
577− */
578−
579−YAML_DECLARE(int)
580−yaml_scalar_event_initialize(yaml_event_t *event,
581− yaml_char_t *anchor, yaml_char_t *tag,
582− yaml_char_t *value, int length,
583− int plain_implicit, int quoted_implicit,
584− yaml_scalar_style_t style);
585−
586−/**
587− * Create a SEQUENCE-START event.
588− *
589− * The @a style argument may be ignored by the emitter.
590− *
591− * Either the @a tag attribute or the @a implicit flag must be set.
592− *
593− * @param[out] event An empty event object.
594− * @param[in] anchor The sequence anchor or @c NULL.
595− * @param[in] tag The sequence tag or @c NULL.
596− * @param[in] implicit If the tag may be omitted.
597− * @param[in] style The sequence style.
598− *
599− * @returns @c 1 if the function succeeded, @c 0 on error.
600− */
601−
602−YAML_DECLARE(int)
603−yaml_sequence_start_event_initialize(yaml_event_t *event,
604− yaml_char_t *anchor, yaml_char_t *tag, int implicit,
605− yaml_sequence_style_t style);
606−
607−/**
608− * Create a SEQUENCE-END event.
609− *
610− * @param[out] event An empty event object.
611− *
612− * @returns @c 1 if the function succeeded, @c 0 on error.
613− */
614−
615−YAML_DECLARE(int)
616−yaml_sequence_end_event_initialize(yaml_event_t *event);
617−
618−/**
619− * Create a MAPPING-START event.
620− *
621− * The @a style argument may be ignored by the emitter.
622− *
623− * Either the @a tag attribute or the @a implicit flag must be set.
624− *
625− * @param[out] event An empty event object.
626− * @param[in] anchor The mapping anchor or @c NULL.
627− * @param[in] tag The mapping tag or @c NULL.
628− * @param[in] implicit If the tag may be omitted.
629− * @param[in] style The mapping style.
630− *
631− * @returns @c 1 if the function succeeded, @c 0 on error.
632− */
633−
634−YAML_DECLARE(int)
635−yaml_mapping_start_event_initialize(yaml_event_t *event,
636− yaml_char_t *anchor, yaml_char_t *tag, int implicit,
637− yaml_mapping_style_t style);
638−
639−/**
640− * Create a MAPPING-END event.
641− *
642− * @param[out] event An empty event object.
643− *
644− * @returns @c 1 if the function succeeded, @c 0 on error.
645− */
646−
647−YAML_DECLARE(int)
648−yaml_mapping_end_event_initialize(yaml_event_t *event);
649−
650−/**
651− * Free any memory allocated for an event object.
652− *
653− * @param[in,out] event An event object.
654− */
655−
656−YAML_DECLARE(void)
657−yaml_event_delete(yaml_event_t *event);
658−
659−/** @} */
660−
661−/**
662− * @defgroup nodes Nodes
663− * @{
664− */
665−
666−/** The tag @c !!null with the only possible value: @c null. */
667−#define YAML_NULL_TAG "tag:yaml.org,2002:null"
668−/** The tag @c !!bool with the values: @c true and @c false. */
669−#define YAML_BOOL_TAG "tag:yaml.org,2002:bool"
670−/** The tag @c !!str for string values. */
671−#define YAML_STR_TAG "tag:yaml.org,2002:str"
672−/** The tag @c !!int for integer values. */
673−#define YAML_INT_TAG "tag:yaml.org,2002:int"
674−/** The tag @c !!float for float values. */
675−#define YAML_FLOAT_TAG "tag:yaml.org,2002:float"
676−/** The tag @c !!timestamp for date and time values. */
677−#define YAML_TIMESTAMP_TAG "tag:yaml.org,2002:timestamp"
678−
679−/** The tag @c !!seq is used to denote sequences. */
680−#define YAML_SEQ_TAG "tag:yaml.org,2002:seq"
681−/** The tag @c !!map is used to denote mapping. */
682−#define YAML_MAP_TAG "tag:yaml.org,2002:map"
683−
684−/** The default scalar tag is @c !!str. */
685−#define YAML_DEFAULT_SCALAR_TAG YAML_STR_TAG
686−/** The default sequence tag is @c !!seq. */
687−#define YAML_DEFAULT_SEQUENCE_TAG YAML_SEQ_TAG
688−/** The default mapping tag is @c !!map. */
689−#define YAML_DEFAULT_MAPPING_TAG YAML_MAP_TAG
690−
691−/** Node types. */
692−typedef enum yaml_node_type_e {
693− /** An empty node. */
694− YAML_NO_NODE,
695−
696− /** A scalar node. */
697− YAML_SCALAR_NODE,
698− /** A sequence node. */
699− YAML_SEQUENCE_NODE,
700− /** A mapping node. */
701− YAML_MAPPING_NODE
702−} yaml_node_type_t;
703−
704−/** The forward definition of a document node structure. */
705−typedef struct yaml_node_s yaml_node_t;
706−
707−/** An element of a sequence node. */
708−typedef int yaml_node_item_t;
709−
710−/** An element of a mapping node. */
711−typedef struct yaml_node_pair_s {
712− /** The key of the element. */
713− int key;
714− /** The value of the element. */
715− int value;
716−} yaml_node_pair_t;
717−
718−/** The node structure. */
719−struct yaml_node_s {
720−
721− /** The node type. */
722− yaml_node_type_t type;
723−
724− /** The node tag. */
725− yaml_char_t *tag;
726−
727− /** The node data. */
728− union {
729−
730− /** The scalar parameters (for @c YAML_SCALAR_NODE). */
731− struct {
732− /** The scalar value. */
733− yaml_char_t *value;
734− /** The length of the scalar value. */
735− size_t length;
736− /** The scalar style. */
737− yaml_scalar_style_t style;
738− } scalar;
739−
740− /** The sequence parameters (for @c YAML_SEQUENCE_NODE). */
741− struct {
742− /** The stack of sequence items. */
743− struct {
744− /** The beginning of the stack. */
745− yaml_node_item_t *start;
746− /** The end of the stack. */
747− yaml_node_item_t *end;
748− /** The top of the stack. */
749− yaml_node_item_t *top;
750− } items;
751− /** The sequence style. */
752− yaml_sequence_style_t style;
753− } sequence;
754−
755− /** The mapping parameters (for @c YAML_MAPPING_NODE). */
756− struct {
757− /** The stack of mapping pairs (key, value). */
758− struct {
759− /** The beginning of the stack. */
760− yaml_node_pair_t *start;
761− /** The end of the stack. */
762− yaml_node_pair_t *end;
763− /** The top of the stack. */
764− yaml_node_pair_t *top;
765− } pairs;
766− /** The mapping style. */
767− yaml_mapping_style_t style;
768− } mapping;
769−
770− } data;
771−
772− /** The beginning of the node. */
773− yaml_mark_t start_mark;
774− /** The end of the node. */
775− yaml_mark_t end_mark;
776−
777−};
778−
779−/** The document structure. */
780−typedef struct yaml_document_s {
781−
782− /** The document nodes. */
783− struct {
784− /** The beginning of the stack. */
785− yaml_node_t *start;
786− /** The end of the stack. */
787− yaml_node_t *end;
788− /** The top of the stack. */
789− yaml_node_t *top;
790− } nodes;
791−
792− /** The version directive. */
793− yaml_version_directive_t *version_directive;
794−
795− /** The list of tag directives. */
796− struct {
797− /** The beginning of the tag directives list. */
798− yaml_tag_directive_t *start;
799− /** The end of the tag directives list. */
800− yaml_tag_directive_t *end;
801− } tag_directives;
802−
803− /** Is the document start indicator implicit? */
804− int start_implicit;
805− /** Is the document end indicator implicit? */
806− int end_implicit;
807−
808− /** The beginning of the document. */
809− yaml_mark_t start_mark;
810− /** The end of the document. */
811− yaml_mark_t end_mark;
812−
813−} yaml_document_t;
814−
815−/**
816− * Create a YAML document.
817− *
818− * @param[out] document An empty document object.
819− * @param[in] version_directive The %YAML directive value or
820− * @c NULL.
821− * @param[in] tag_directives_start The beginning of the %TAG
822− * directives list.
823− * @param[in] tag_directives_end The end of the %TAG directives
824− * list.
825− * @param[in] start_implicit If the document start indicator is
826− * implicit.
827− * @param[in] end_implicit If the document end indicator is
828− * implicit.
829− *
830− * @returns @c 1 if the function succeeded, @c 0 on error.
831− */
832−
833−YAML_DECLARE(int)
834−yaml_document_initialize(yaml_document_t *document,
835− yaml_version_directive_t *version_directive,
836− yaml_tag_directive_t *tag_directives_start,
837− yaml_tag_directive_t *tag_directives_end,
838− int start_implicit, int end_implicit);
839−
840−/**
841− * Delete a YAML document and all its nodes.
842− *
843− * @param[in,out] document A document object.
844− */
845−
846−YAML_DECLARE(void)
847−yaml_document_delete(yaml_document_t *document);
848−
849−/**
850− * Get a node of a YAML document.
851− *
852− * The pointer returned by this function is valid until any of the functions
853− * modifying the documents are called.
854− *
855− * @param[in] document A document object.
856− * @param[in] index The node id.
857− *
858− * @returns the node objct or @c NULL if @c node_id is out of range.
859− */
860−
861−YAML_DECLARE(yaml_node_t *)
862−yaml_document_get_node(yaml_document_t *document, int index);
863−
864−/**
865− * Get the root of a YAML document node.
866− *
867− * The root object is the first object added to the document.
868− *
869− * The pointer returned by this function is valid until any of the functions
870− * modifying the documents are called.
871− *
872− * An empty document produced by the parser signifies the end of a YAML
873− * stream.
874− *
875− * @param[in] document A document object.
876− *
877− * @returns the node object or @c NULL if the document is empty.
878− */
879−
880−YAML_DECLARE(yaml_node_t *)
881−yaml_document_get_root_node(yaml_document_t *document);
882−
883−/**
884− * Create a SCALAR node and attach it to the document.
885− *
886− * The @a style argument may be ignored by the emitter.
887− *
888− * @param[in,out] document A document object.
889− * @param[in] tag The scalar tag.
890− * @param[in] value The scalar value.
891− * @param[in] length The length of the scalar value.
892− * @param[in] style The scalar style.
893− *
894− * @returns the node id or @c 0 on error.
895− */
896−
897−YAML_DECLARE(int)
898−yaml_document_add_scalar(yaml_document_t *document,
899− yaml_char_t *tag, yaml_char_t *value, int length,
900− yaml_scalar_style_t style);
901−
902−/**
903− * Create a SEQUENCE node and attach it to the document.
904− *
905− * The @a style argument may be ignored by the emitter.
906− *
907− * @param[in,out] document A document object.
908− * @param[in] tag The sequence tag.
909− * @param[in] style The sequence style.
910− *
911− * @returns the node id or @c 0 on error.
912− */
913−
914−YAML_DECLARE(int)
915−yaml_document_add_sequence(yaml_document_t *document,
916− yaml_char_t *tag, yaml_sequence_style_t style);
917−
918−/**
919− * Create a MAPPING node and attach it to the document.
920− *
921− * The @a style argument may be ignored by the emitter.
922− *
923− * @param[in,out] document A document object.
924− * @param[in] tag The sequence tag.
925− * @param[in] style The sequence style.
926− *
927− * @returns the node id or @c 0 on error.
928− */
929−
930−YAML_DECLARE(int)
931−yaml_document_add_mapping(yaml_document_t *document,
932− yaml_char_t *tag, yaml_mapping_style_t style);
933−
934−/**
935− * Add an item to a SEQUENCE node.
936− *
937− * @param[in,out] document A document object.
938− * @param[in] sequence The sequence node id.
939− * @param[in] item The item node id.
940−*
941− * @returns @c 1 if the function succeeded, @c 0 on error.
942− */
943−
944−YAML_DECLARE(int)
945−yaml_document_append_sequence_item(yaml_document_t *document,
946− int sequence, int item);
947−
948−/**
949− * Add a pair of a key and a value to a MAPPING node.
950− *
951− * @param[in,out] document A document object.
952− * @param[in] mapping The mapping node id.
953− * @param[in] key The key node id.
954− * @param[in] value The value node id.
955−*
956− * @returns @c 1 if the function succeeded, @c 0 on error.
957− */
958−
959−YAML_DECLARE(int)
960−yaml_document_append_mapping_pair(yaml_document_t *document,
961− int mapping, int key, int value);
962−
963−/** @} */
964−
965−/**
966− * @defgroup parser Parser Definitions
967− * @{
968− */
969−
970−/**
971− * The prototype of a read handler.
972− *
973− * The read handler is called when the parser needs to read more bytes from the
974− * source. The handler should write not more than @a size bytes to the @a
975− * buffer. The number of written bytes should be set to the @a length variable.
976− *
977− * @param[in,out] data A pointer to an application data specified by
978− * yaml_parser_set_input().
979− * @param[out] buffer The buffer to write the data from the source.
980− * @param[in] size The size of the buffer.
981− * @param[out] size_read The actual number of bytes read from the source.
982− *
983− * @returns On success, the handler should return @c 1. If the handler failed,
984− * the returned value should be @c 0. On EOF, the handler should set the
985− * @a size_read to @c 0 and return @c 1.
986− */
987−
988−typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size,
989− size_t *size_read);
990−
991−/**
992− * This structure holds information about a potential simple key.
993− */
994−
995−typedef struct yaml_simple_key_s {
996− /** Is a simple key possible? */
997− int possible;
998−
999− /** Is a simple key required? */
1000− int required;
1001−
1002− /** The number of the token. */
1003− size_t token_number;
1004−
1005− /** The position mark. */
1006− yaml_mark_t mark;
1007−} yaml_simple_key_t;
1008−
1009−/**
1010− * The states of the parser.
1011− */
1012−typedef enum yaml_parser_state_e {
1013− /** Expect STREAM-START. */
1014− YAML_PARSE_STREAM_START_STATE,
1015− /** Expect the beginning of an implicit document. */
1016− YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE,
1017− /** Expect DOCUMENT-START. */
1018− YAML_PARSE_DOCUMENT_START_STATE,
1019− /** Expect the content of a document. */
1020− YAML_PARSE_DOCUMENT_CONTENT_STATE,
1021− /** Expect DOCUMENT-END. */
1022− YAML_PARSE_DOCUMENT_END_STATE,
1023− /** Expect a block node. */
1024− YAML_PARSE_BLOCK_NODE_STATE,
1025− /** Expect a block node or indentless sequence. */
1026− YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE,
1027− /** Expect a flow node. */
1028− YAML_PARSE_FLOW_NODE_STATE,
1029− /** Expect the first entry of a block sequence. */
1030− YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE,
1031− /** Expect an entry of a block sequence. */
1032− YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE,
1033− /** Expect an entry of an indentless sequence. */
1034− YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE,
1035− /** Expect the first key of a block mapping. */
1036− YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE,
1037− /** Expect a block mapping key. */
1038− YAML_PARSE_BLOCK_MAPPING_KEY_STATE,
1039− /** Expect a block mapping value. */
1040− YAML_PARSE_BLOCK_MAPPING_VALUE_STATE,
1041− /** Expect the first entry of a flow sequence. */
1042− YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE,
1043− /** Expect an entry of a flow sequence. */
1044− YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE,
1045− /** Expect a key of an ordered mapping. */
1046− YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE,
1047− /** Expect a value of an ordered mapping. */
1048− YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE,
1049− /** Expect the and of an ordered mapping entry. */
1050− YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE,
1051− /** Expect the first key of a flow mapping. */
1052− YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE,
1053− /** Expect a key of a flow mapping. */
1054− YAML_PARSE_FLOW_MAPPING_KEY_STATE,
1055− /** Expect a value of a flow mapping. */
1056− YAML_PARSE_FLOW_MAPPING_VALUE_STATE,
1057− /** Expect an empty value of a flow mapping. */
1058− YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE,
1059− /** Expect nothing. */
1060− YAML_PARSE_END_STATE
1061−} yaml_parser_state_t;
1062−
1063−/**
1064− * This structure holds aliases data.
1065− */
1066−
1067−typedef struct yaml_alias_data_s {
1068− /** The anchor. */
1069− yaml_char_t *anchor;
1070− /** The node id. */
1071− int index;
1072− /** The anchor mark. */
1073− yaml_mark_t mark;
1074−} yaml_alias_data_t;
1075−
1076−/**
1077− * The parser structure.
1078− *
1079− * All members are internal. Manage the structure using the @c yaml_parser_
1080− * family of functions.
1081− */
1082−
1083−typedef struct yaml_parser_s {
1084−
1085− /**
1086− * @name Error handling
1087− * @{
1088− */
1089−
1090− /** Error type. */
1091− yaml_error_type_t error;
1092− /** Error description. */
1093− const char *problem;
1094− /** The byte about which the problem occured. */
1095− size_t problem_offset;
1096− /** The problematic value (@c -1 is none). */
1097− int problem_value;
1098− /** The problem position. */
1099− yaml_mark_t problem_mark;
1100− /** The error context. */
1101− const char *context;
1102− /** The context position. */
1103− yaml_mark_t context_mark;
1104−
1105− /**
1106− * @}
1107− */
1108−
1109− /**
1110− * @name Reader stuff
1111− * @{
1112− */
1113−
1114− /** Read handler. */
1115− yaml_read_handler_t *read_handler;
1116−
1117− /** A pointer for passing to the read handler. */
1118− void *read_handler_data;
1119−
1120− /** Standard (string or file) input data. */
1121− union {
1122− /** String input data. */
1123− struct {
1124− /** The string start pointer. */
1125− const unsigned char *start;
1126− /** The string end pointer. */
1127− const unsigned char *end;
1128− /** The string current position. */
1129− const unsigned char *current;
1130− } string;
1131−
1132− /** File input data. */
1133− FILE *file;
1134− } input;
1135−
1136− /** EOF flag */
1137− int eof;
1138−
1139− /** The working buffer. */
1140− struct {
1141− /** The beginning of the buffer. */
1142− yaml_char_t *start;
1143− /** The end of the buffer. */
1144− yaml_char_t *end;
1145− /** The current position of the buffer. */
1146− yaml_char_t *pointer;
1147− /** The last filled position of the buffer. */
1148− yaml_char_t *last;
1149− } buffer;
1150−
1151− /* The number of unread characters in the buffer. */
1152− size_t unread;
1153−
1154− /** The raw buffer. */
1155− struct {
1156− /** The beginning of the buffer. */
1157− unsigned char *start;
1158− /** The end of the buffer. */
1159− unsigned char *end;
1160− /** The current position of the buffer. */
1161− unsigned char *pointer;
1162− /** The last filled position of the buffer. */
1163− unsigned char *last;
1164− } raw_buffer;
1165−
1166− /** The input encoding. */
1167− yaml_encoding_t encoding;
1168−
1169− /** The offset of the current position (in bytes). */
1170− size_t offset;
1171−
1172− /** The mark of the current position. */
1173− yaml_mark_t mark;
1174−
1175− /**
1176− * @}
1177− */
1178−
1179− /**
1180− * @name Scanner stuff
1181− * @{
1182− */
1183−
1184− /** Have we started to scan the input stream? */
1185− int stream_start_produced;
1186−
1187− /** Have we reached the end of the input stream? */
1188− int stream_end_produced;
1189−
1190− /** The number of unclosed '[' and '{' indicators. */
1191− int flow_level;
1192−
1193− /** The tokens queue. */
1194− struct {
1195− /** The beginning of the tokens queue. */
1196− yaml_token_t *start;
1197− /** The end of the tokens queue. */
1198− yaml_token_t *end;
1199− /** The head of the tokens queue. */
1200− yaml_token_t *head;
1201− /** The tail of the tokens queue. */
1202− yaml_token_t *tail;
1203− } tokens;
1204−
1205− /** The number of tokens fetched from the queue. */
1206− size_t tokens_parsed;
1207−
1208− /* Does the tokens queue contain a token ready for dequeueing. */
1209− int token_available;
1210−
1211− /** The indentation levels stack. */
1212− struct {
1213− /** The beginning of the stack. */
1214− int *start;
1215− /** The end of the stack. */
1216− int *end;
1217− /** The top of the stack. */
1218− int *top;
1219− } indents;
1220−
1221− /** The current indentation level. */
1222− int indent;
1223−
1224− /** May a simple key occur at the current position? */
1225− int simple_key_allowed;
1226−
1227− /** The stack of simple keys. */
1228− struct {
1229− /** The beginning of the stack. */
1230− yaml_simple_key_t *start;
1231− /** The end of the stack. */
1232− yaml_simple_key_t *end;
1233− /** The top of the stack. */
1234− yaml_simple_key_t *top;
1235− } simple_keys;
1236−
1237− /**
1238− * @}
1239− */
1240−
1241− /**
1242− * @name Parser stuff
1243− * @{
1244− */
1245−
1246− /** The parser states stack. */
1247− struct {
1248− /** The beginning of the stack. */
1249− yaml_parser_state_t *start;
1250− /** The end of the stack. */
1251− yaml_parser_state_t *end;
1252− /** The top of the stack. */
1253− yaml_parser_state_t *top;
1254− } states;
1255−
1256− /** The current parser state. */
1257− yaml_parser_state_t state;
1258−
1259− /** The stack of marks. */
1260− struct {
1261− /** The beginning of the stack. */
1262− yaml_mark_t *start;
1263− /** The end of the stack. */
1264− yaml_mark_t *end;
1265− /** The top of the stack. */
1266− yaml_mark_t *top;
1267− } marks;
1268−
1269− /** The list of TAG directives. */
1270− struct {
1271− /** The beginning of the list. */
1272− yaml_tag_directive_t *start;
1273− /** The end of the list. */
1274− yaml_tag_directive_t *end;
1275− /** The top of the list. */
1276− yaml_tag_directive_t *top;
1277− } tag_directives;
1278−
1279− /**
1280− * @}
1281− */
1282−
1283− /**
1284− * @name Dumper stuff
1285− * @{
1286− */
1287−
1288− /** The alias data. */
1289− struct {
1290− /** The beginning of the list. */
1291− yaml_alias_data_t *start;
1292− /** The end of the list. */
1293− yaml_alias_data_t *end;
1294− /** The top of the list. */
1295− yaml_alias_data_t *top;
1296− } aliases;
1297−
1298− /** The currently parsed document. */
1299− yaml_document_t *document;
1300−
1301− /**
1302− * @}
1303− */
1304−
1305−} yaml_parser_t;
1306−
1307−/**
1308− * Initialize a parser.
1309− *
1310− * This function creates a new parser object. An application is responsible
1311− * for destroying the object using the yaml_parser_delete() function.
1312− *
1313− * @param[out] parser An empty parser object.
1314− *
1315− * @returns @c 1 if the function succeeded, @c 0 on error.
1316− */
1317−
1318−YAML_DECLARE(int)
1319−yaml_parser_initialize(yaml_parser_t *parser);
1320−
1321−/**
1322− * Destroy a parser.
1323− *
1324− * @param[in,out] parser A parser object.
1325− */
1326−
1327−YAML_DECLARE(void)
1328−yaml_parser_delete(yaml_parser_t *parser);
1329−
1330−/**
1331− * Set a string input.
1332− *
1333− * Note that the @a input pointer must be valid while the @a parser object
1334− * exists. The application is responsible for destroing @a input after
1335− * destroying the @a parser.
1336− *
1337− * @param[in,out] parser A parser object.
1338− * @param[in] input A source data.
1339− * @param[in] size The length of the source data in bytes.
1340− */
1341−
1342−YAML_DECLARE(void)
1343−yaml_parser_set_input_string(yaml_parser_t *parser,
1344− const unsigned char *input, size_t size);
1345−
1346−/**
1347− * Set a file input.
1348− *
1349− * @a file should be a file object open for reading. The application is
1350− * responsible for closing the @a file.
1351− *
1352− * @param[in,out] parser A parser object.
1353− * @param[in] file An open file.
1354− */
1355−
1356−YAML_DECLARE(void)
1357−yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file);
1358−
1359−/**
1360− * Set a generic input handler.
1361− *
1362− * @param[in,out] parser A parser object.
1363− * @param[in] handler A read handler.
1364− * @param[in] data Any application data for passing to the read
1365− * handler.
1366− */
1367−
1368−YAML_DECLARE(void)
1369−yaml_parser_set_input(yaml_parser_t *parser,
1370− yaml_read_handler_t *handler, void *data);
1371−
1372−/**
1373− * Set the source encoding.
1374− *
1375− * @param[in,out] parser A parser object.
1376− * @param[in] encoding The source encoding.
1377− */
1378−
1379−YAML_DECLARE(void)
1380−yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding);
1381−
1382−/**
1383− * Scan the input stream and produce the next token.
1384− *
1385− * Call the function subsequently to produce a sequence of tokens corresponding
1386− * to the input stream. The initial token has the type
1387− * @c YAML_STREAM_START_TOKEN while the ending token has the type
1388− * @c YAML_STREAM_END_TOKEN.
1389− *
1390− * An application is responsible for freeing any buffers associated with the
1391− * produced token object using the @c yaml_token_delete function.
1392− *
1393− * An application must not alternate the calls of yaml_parser_scan() with the
1394− * calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break
1395− * the parser.
1396− *
1397− * @param[in,out] parser A parser object.
1398− * @param[out] token An empty token object.
1399− *
1400− * @returns @c 1 if the function succeeded, @c 0 on error.
1401− */
1402−
1403−YAML_DECLARE(int)
1404−yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token);
1405−
1406−/**
1407− * Parse the input stream and produce the next parsing event.
1408− *
1409− * Call the function subsequently to produce a sequence of events corresponding
1410− * to the input stream. The initial event has the type
1411− * @c YAML_STREAM_START_EVENT while the ending event has the type
1412− * @c YAML_STREAM_END_EVENT.
1413− *
1414− * An application is responsible for freeing any buffers associated with the
1415− * produced event object using the yaml_event_delete() function.
1416− *
1417− * An application must not alternate the calls of yaml_parser_parse() with the
1418− * calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the
1419− * parser.
1420− *
1421− * @param[in,out] parser A parser object.
1422− * @param[out] event An empty event object.
1423− *
1424− * @returns @c 1 if the function succeeded, @c 0 on error.
1425− */
1426−
1427−YAML_DECLARE(int)
1428−yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event);
1429−
1430−/**
1431− * Parse the input stream and produce the next YAML document.
1432− *
1433− * Call this function subsequently to produce a sequence of documents
1434− * constituting the input stream.
1435− *
1436− * If the produced document has no root node, it means that the document
1437− * end has been reached.
1438− *
1439− * An application is responsible for freeing any data associated with the
1440− * produced document object using the yaml_document_delete() function.
1441− *
1442− * An application must not alternate the calls of yaml_parser_load() with the
1443− * calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break
1444− * the parser.
1445− *
1446− * @param[in,out] parser A parser object.
1447− * @param[out] document An empty document object.
1448− *
1449− * @return @c 1 if the function succeeded, @c 0 on error.
1450− */
1451−
1452−YAML_DECLARE(int)
1453−yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
1454−
1455−/** @} */
1456−
1457−/**
1458− * @defgroup emitter Emitter Definitions
1459− * @{
1460− */
1461−
1462−/**
1463− * The prototype of a write handler.
1464− *
1465− * The write handler is called when the emitter needs to flush the accumulated
1466− * characters to the output. The handler should write @a size bytes of the
1467− * @a buffer to the output.
1468− *
1469− * @param[in,out] data A pointer to an application data specified by
1470− * yaml_emitter_set_output().
1471− * @param[in] buffer The buffer with bytes to be written.
1472− * @param[in] size The size of the buffer.
1473− *
1474− * @returns On success, the handler should return @c 1. If the handler failed,
1475− * the returned value should be @c 0.
1476− */
1477−
1478−typedef int yaml_write_handler_t(void *data, unsigned char *buffer, size_t size);
1479−
1480−/** The emitter states. */
1481−typedef enum yaml_emitter_state_e {
1482− /** Expect STREAM-START. */
1483− YAML_EMIT_STREAM_START_STATE,
1484− /** Expect the first DOCUMENT-START or STREAM-END. */
1485− YAML_EMIT_FIRST_DOCUMENT_START_STATE,
1486− /** Expect DOCUMENT-START or STREAM-END. */
1487− YAML_EMIT_DOCUMENT_START_STATE,
1488− /** Expect the content of a document. */
1489− YAML_EMIT_DOCUMENT_CONTENT_STATE,
1490− /** Expect DOCUMENT-END. */
1491− YAML_EMIT_DOCUMENT_END_STATE,
1492− /** Expect the first item of a flow sequence. */
1493− YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE,
1494− /** Expect an item of a flow sequence. */
1495− YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE,
1496− /** Expect the first key of a flow mapping. */
1497− YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE,
1498− /** Expect a key of a flow mapping. */
1499− YAML_EMIT_FLOW_MAPPING_KEY_STATE,
1500− /** Expect a value for a simple key of a flow mapping. */
1501− YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE,
1502− /** Expect a value of a flow mapping. */
1503− YAML_EMIT_FLOW_MAPPING_VALUE_STATE,
1504− /** Expect the first item of a block sequence. */
1505− YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE,
1506− /** Expect an item of a block sequence. */
1507− YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE,
1508− /** Expect the first key of a block mapping. */
1509− YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE,
1510− /** Expect the key of a block mapping. */
1511− YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
1512− /** Expect a value for a simple key of a block mapping. */
1513− YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE,
1514− /** Expect a value of a block mapping. */
1515− YAML_EMIT_BLOCK_MAPPING_VALUE_STATE,
1516− /** Expect nothing. */
1517− YAML_EMIT_END_STATE
1518−} yaml_emitter_state_t;
1519−
1520−/**
1521− * The emitter structure.
1522− *
1523− * All members are internal. Manage the structure using the @c yaml_emitter_
1524− * family of functions.
1525− */
1526−
1527−typedef struct yaml_emitter_s {
1528−
1529− /**
1530− * @name Error handling
1531− * @{
1532− */
1533−
1534− /** Error type. */
1535− yaml_error_type_t error;
1536− /** Error description. */
1537− const char *problem;
1538−
1539− /**
1540− * @}
1541− */
1542−
1543− /**
1544− * @name Writer stuff
1545− * @{
1546− */
1547−
1548− /** Write handler. */
1549− yaml_write_handler_t *write_handler;
1550−
1551− /** A pointer for passing to the white handler. */
1552− void *write_handler_data;
1553−
1554− /** Standard (string or file) output data. */
1555− union {
1556− /** String output data. */
1557− struct {
1558− /** The buffer pointer. */
1559− unsigned char *buffer;
1560− /** The buffer size. */
1561− size_t size;
1562− /** The number of written bytes. */
1563− size_t *size_written;
1564− } string;
1565−
1566− /** File output data. */
1567− FILE *file;
1568− } output;
1569−
1570− /** The working buffer. */
1571− struct {
1572− /** The beginning of the buffer. */
1573− yaml_char_t *start;
1574− /** The end of the buffer. */
1575− yaml_char_t *end;
1576− /** The current position of the buffer. */
1577− yaml_char_t *pointer;
1578− /** The last filled position of the buffer. */
1579− yaml_char_t *last;
1580− } buffer;
1581−
1582− /** The raw buffer. */
1583− struct {
1584− /** The beginning of the buffer. */
1585− unsigned char *start;
1586− /** The end of the buffer. */
1587− unsigned char *end;
1588− /** The current position of the buffer. */
1589− unsigned char *pointer;
1590− /** The last filled position of the buffer. */
1591− unsigned char *last;
1592− } raw_buffer;
1593−
1594− /** The stream encoding. */
1595− yaml_encoding_t encoding;
1596−
1597− /**
1598− * @}
1599− */
1600−
1601− /**
1602− * @name Emitter stuff
1603− * @{
1604− */
1605−
1606− /** If the output is in the canonical style? */
1607− int canonical;
1608− /** The number of indentation spaces. */
1609− int best_indent;
1610− /** The preferred width of the output lines. */
1611− int best_width;
1612− /** Allow unescaped non-ASCII characters? */
1613− int unicode;
1614− /** The preferred line break. */
1615− yaml_break_t line_break;
1616−
1617− /** The stack of states. */
1618− struct {
1619− /** The beginning of the stack. */
1620− yaml_emitter_state_t *start;
1621− /** The end of the stack. */
1622− yaml_emitter_state_t *end;
1623− /** The top of the stack. */
1624− yaml_emitter_state_t *top;
1625− } states;
1626−
1627− /** The current emitter state. */
1628− yaml_emitter_state_t state;
1629−
1630− /** The event queue. */
1631− struct {
1632− /** The beginning of the event queue. */
1633− yaml_event_t *start;
1634− /** The end of the event queue. */
1635− yaml_event_t *end;
1636− /** The head of the event queue. */
1637− yaml_event_t *head;
1638− /** The tail of the event queue. */
1639− yaml_event_t *tail;
1640− } events;
1641−
1642− /** The stack of indentation levels. */
1643− struct {
1644− /** The beginning of the stack. */
1645− int *start;
1646− /** The end of the stack. */
1647− int *end;
1648− /** The top of the stack. */
1649− int *top;
1650− } indents;
1651−
1652− /** The list of tag directives. */
1653− struct {
1654− /** The beginning of the list. */
1655− yaml_tag_directive_t *start;
1656− /** The end of the list. */
1657− yaml_tag_directive_t *end;
1658− /** The top of the list. */
1659− yaml_tag_directive_t *top;
1660− } tag_directives;
1661−
1662− /** The current indentation level. */
1663− int indent;
1664−
1665− /** The current flow level. */
1666− int flow_level;
1667−
1668− /** Is it the document root context? */
1669− int root_context;
1670− /** Is it a sequence context? */
1671− int sequence_context;
1672− /** Is it a mapping context? */
1673− int mapping_context;
1674− /** Is it a simple mapping key context? */
1675− int simple_key_context;
1676−
1677− /** The current line. */
1678− int line;
1679− /** The current column. */
1680− int column;
1681− /** If the last character was a whitespace? */
1682− int whitespace;
1683− /** If the last character was an indentation character (' ', '-', '?', ':')? */
1684− int indention;
1685− /** If an explicit document end is required? */
1686− int open_ended;
1687−
1688− /** Anchor analysis. */
1689− struct {
1690− /** The anchor value. */
1691− yaml_char_t *anchor;
1692− /** The anchor length. */
1693− size_t anchor_length;
1694− /** Is it an alias? */
1695− int alias;
1696− } anchor_data;
1697−
1698− /** Tag analysis. */
1699− struct {
1700− /** The tag handle. */
1701− yaml_char_t *handle;
1702− /** The tag handle length. */
1703− size_t handle_length;
1704− /** The tag suffix. */
1705− yaml_char_t *suffix;
1706− /** The tag suffix length. */
1707− size_t suffix_length;
1708− } tag_data;
1709−
1710− /** Scalar analysis. */
1711− struct {
1712− /** The scalar value. */
1713− yaml_char_t *value;
1714− /** The scalar length. */
1715− size_t length;
1716− /** Does the scalar contain line breaks? */
1717− int multiline;
1718− /** Can the scalar be expessed in the flow plain style? */
1719− int flow_plain_allowed;
1720− /** Can the scalar be expressed in the block plain style? */
1721− int block_plain_allowed;
1722− /** Can the scalar be expressed in the single quoted style? */
1723− int single_quoted_allowed;
1724− /** Can the scalar be expressed in the literal or folded styles? */
1725− int block_allowed;
1726− /** The output style. */
1727− yaml_scalar_style_t style;
1728− } scalar_data;
1729−
1730− /**
1731− * @}
1732− */
1733−
1734− /**
1735− * @name Dumper stuff
1736− * @{
1737− */
1738−
1739− /** If the stream was already opened? */
1740− int opened;
1741− /** If the stream was already closed? */
1742− int closed;
1743−
1744− /** The information associated with the document nodes. */
1745− struct {
1746− /** The number of references. */
1747− int references;
1748− /** The anchor id. */
1749− int anchor;
1750− /** If the node has been emitted? */
1751− int serialized;
1752− } *anchors;
1753−
1754− /** The last assigned anchor id. */
1755− int last_anchor_id;
1756−
1757− /** The currently emitted document. */
1758− yaml_document_t *document;
1759−
1760− /**
1761− * @}
1762− */
1763−
1764−} yaml_emitter_t;
1765−
1766−/**
1767− * Initialize an emitter.
1768− *
1769− * This function creates a new emitter object. An application is responsible
1770− * for destroying the object using the yaml_emitter_delete() function.
1771− *
1772− * @param[out] emitter An empty parser object.
1773− *
1774− * @returns @c 1 if the function succeeded, @c 0 on error.
1775− */
1776−
1777−YAML_DECLARE(int)
1778−yaml_emitter_initialize(yaml_emitter_t *emitter);
1779−
1780−/**
1781− * Destroy an emitter.
1782− *
1783− * @param[in,out] emitter An emitter object.
1784− */
1785−
1786−YAML_DECLARE(void)
1787−yaml_emitter_delete(yaml_emitter_t *emitter);
1788−
1789−/**
1790− * Set a string output.
1791− *
1792− * The emitter will write the output characters to the @a output buffer of the
1793− * size @a size. The emitter will set @a size_written to the number of written
1794− * bytes. If the buffer is smaller than required, the emitter produces the
1795− * YAML_WRITE_ERROR error.
1796− *
1797− * @param[in,out] emitter An emitter object.
1798− * @param[in] output An output buffer.
1799− * @param[in] size The buffer size.
1800− * @param[in] size_written The pointer to save the number of written
1801− * bytes.
1802− */
1803−
1804−YAML_DECLARE(void)
1805−yaml_emitter_set_output_string(yaml_emitter_t *emitter,
1806− unsigned char *output, size_t size, size_t *size_written);
1807−
1808−/**
1809− * Set a file output.
1810− *
1811− * @a file should be a file object open for writing. The application is
1812− * responsible for closing the @a file.
1813− *
1814− * @param[in,out] emitter An emitter object.
1815− * @param[in] file An open file.
1816− */
1817−
1818−YAML_DECLARE(void)
1819−yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file);
1820−
1821−/**
1822− * Set a generic output handler.
1823− *
1824− * @param[in,out] emitter An emitter object.
1825− * @param[in] handler A write handler.
1826− * @param[in] data Any application data for passing to the write
1827− * handler.
1828− */
1829−
1830−YAML_DECLARE(void)
1831−yaml_emitter_set_output(yaml_emitter_t *emitter,
1832− yaml_write_handler_t *handler, void *data);
1833−
1834−/**
1835− * Set the output encoding.
1836− *
1837− * @param[in,out] emitter An emitter object.
1838− * @param[in] encoding The output encoding.
1839− */
1840−
1841−YAML_DECLARE(void)
1842−yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding);
1843−
1844−/**
1845− * Set if the output should be in the "canonical" format as in the YAML
1846− * specification.
1847− *
1848− * @param[in,out] emitter An emitter object.
1849− * @param[in] canonical If the output is canonical.
1850− */
1851−
1852−YAML_DECLARE(void)
1853−yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical);
1854−
1855−/**
1856− * Set the intendation increment.
1857− *
1858− * @param[in,out] emitter An emitter object.
1859− * @param[in] indent The indentation increment (1 < . < 10).
1860− */
1861−
1862−YAML_DECLARE(void)
1863−yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent);
1864−
1865−/**
1866− * Set the preferred line width. @c -1 means unlimited.
1867− *
1868− * @param[in,out] emitter An emitter object.
1869− * @param[in] width The preferred line width.
1870− */
1871−
1872−YAML_DECLARE(void)
1873−yaml_emitter_set_width(yaml_emitter_t *emitter, int width);
1874−
1875−/**
1876− * Set if unescaped non-ASCII characters are allowed.
1877− *
1878− * @param[in,out] emitter An emitter object.
1879− * @param[in] unicode If unescaped Unicode characters are allowed.
1880− */
1881−
1882−YAML_DECLARE(void)
1883−yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode);
1884−
1885−/**
1886− * Set the preferred line break.
1887− *
1888− * @param[in,out] emitter An emitter object.
1889− * @param[in] line_break The preferred line break.
1890− */
1891−
1892−YAML_DECLARE(void)
1893−yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break);
1894−
1895−/**
1896− * Emit an event.
1897− *
1898− * The event object may be generated using the yaml_parser_parse() function.
1899− * The emitter takes the responsibility for the event object and destroys its
1900− * content after it is emitted. The event object is destroyed even if the
1901− * function fails.
1902− *
1903− * @param[in,out] emitter An emitter object.
1904− * @param[in,out] event An event object.
1905− *
1906− * @returns @c 1 if the function succeeded, @c 0 on error.
1907− */
1908−
1909−YAML_DECLARE(int)
1910−yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event);
1911−
1912−/**
1913− * Start a YAML stream.
1914− *
1915− * This function should be used before yaml_emitter_dump() is called.
1916− *
1917− * @param[in,out] emitter An emitter object.
1918− *
1919− * @returns @c 1 if the function succeeded, @c 0 on error.
1920− */
1921−
1922−YAML_DECLARE(int)
1923−yaml_emitter_open(yaml_emitter_t *emitter);
1924−
1925−/**
1926− * Finish a YAML stream.
1927− *
1928− * This function should be used after yaml_emitter_dump() is called.
1929− *
1930− * @param[in,out] emitter An emitter object.
1931− *
1932− * @returns @c 1 if the function succeeded, @c 0 on error.
1933− */
1934−
1935−YAML_DECLARE(int)
1936−yaml_emitter_close(yaml_emitter_t *emitter);
1937−
1938−/**
1939− * Emit a YAML document.
1940− *
1941− * The documen object may be generated using the yaml_parser_load() function
1942− * or the yaml_document_initialize() function. The emitter takes the
1943− * responsibility for the document object and destroys its content after
1944− * it is emitted. The document object is destroyed even if the function fails.
1945− *
1946− * @param[in,out] emitter An emitter object.
1947− * @param[in,out] document A document object.
1948− *
1949− * @returns @c 1 if the function succeeded, @c 0 on error.
1950− */
1951−
1952−YAML_DECLARE(int)
1953−yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
1954−
1955−/**
1956− * Flush the accumulated characters to the output.
1957− *
1958− * @param[in,out] emitter An emitter object.
1959− *
1960− * @returns @c 1 if the function succeeded, @c 0 on error.
1961− */
1962−
1963−YAML_DECLARE(int)
1964−yaml_emitter_flush(yaml_emitter_t *emitter);
1965−
1966−/** @} */
1967−
1968−#ifdef __cplusplus
1969−}
1970−#endif
1971−
1972−#endif /* #ifndef YAML_H */
1973−
libyaml/yaml_private.hdeleted−690
@@ -1,690 +0,0 @@
1−#if HAVE_CONFIG_H
2−#include <config.h>
3−#endif
4−
5−#include <yaml.h>
6−
7−#include <assert.h>
8−#include <limits.h>
9−#include <stddef.h>
10−
11−/*
12− * Memory management.
13− */
14−
15−YAML_DECLARE(void *)
16−yaml_malloc(size_t size);
17−
18−YAML_DECLARE(void *)
19−yaml_realloc(void *ptr, size_t size);
20−
21−YAML_DECLARE(void)
22−yaml_free(void *ptr);
23−
24−YAML_DECLARE(yaml_char_t *)
25−yaml_strdup(const yaml_char_t *);
26−
27−/*
28− * Reader: Ensure that the buffer contains at least `length` characters.
29− */
30−
31−YAML_DECLARE(int)
32−yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
33−
34−/*
35− * Scanner: Ensure that the token stack contains at least one token ready.
36− */
37−
38−YAML_DECLARE(int)
39−yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
40−
41−/*
42− * The size of the input raw buffer.
43− */
44−
45−#define INPUT_RAW_BUFFER_SIZE 16384
46−
47−/*
48− * The size of the input buffer.
49− *
50− * It should be possible to decode the whole raw buffer.
51− */
52−
53−#define INPUT_BUFFER_SIZE (INPUT_RAW_BUFFER_SIZE*3)
54−
55−/*
56− * The size of the output buffer.
57− */
58−
59−#define OUTPUT_BUFFER_SIZE 16384
60−
61−/*
62− * The size of the output raw buffer.
63− *
64− * It should be possible to encode the whole output buffer.
65− */
66−
67−#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2)
68−
69−/*
70− * The maximum size of a YAML input file.
71− * This used to be PTRDIFF_MAX, but that's not entirely portable
72− * because stdint.h isn't available on all platforms.
73− * It is not entirely clear why this isn't the maximum value
74− * that can fit into the parser->offset field.
75− */
76−
77−#define MAX_FILE_SIZE (~(size_t)0 / 2)
78−
79−
80−/*
81− * The size of other stacks and queues.
82− */
83−
84−#define INITIAL_STACK_SIZE 16
85−#define INITIAL_QUEUE_SIZE 16
86−#define INITIAL_STRING_SIZE 16
87−
88−/*
89− * Buffer management.
90− */
91−
92−#define BUFFER_INIT(context,buffer,size) \
93− (((buffer).start = (yaml_char_t *)yaml_malloc(size)) ? \
94− ((buffer).last = (buffer).pointer = (buffer).start, \
95− (buffer).end = (buffer).start+(size), \
96− 1) : \
97− ((context)->error = YAML_MEMORY_ERROR, \
98− 0))
99−
100−#define BUFFER_DEL(context,buffer) \
101− (yaml_free((buffer).start), \
102− (buffer).start = (buffer).pointer = (buffer).end = 0)
103−
104−/*
105− * String management.
106− */
107−
108−typedef struct {
109− yaml_char_t *start;
110− yaml_char_t *end;
111− yaml_char_t *pointer;
112−} yaml_string_t;
113−
114−YAML_DECLARE(int)
115−yaml_string_extend(yaml_char_t **start,
116− yaml_char_t **pointer, yaml_char_t **end);
117−
118−YAML_DECLARE(int)
119−yaml_string_join(
120− yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
121− yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end);
122−
123−#define NULL_STRING { NULL, NULL, NULL }
124−
125−#define STRING(string,length) { (string), (string)+(length), (string) }
126−
127−#define STRING_ASSIGN(value,string,length) \
128− ((value).start = (string), \
129− (value).end = (string)+(length), \
130− (value).pointer = (string))
131−
132−#define STRING_INIT(context,string,size) \
133− (((string).start = YAML_MALLOC(size)) ? \
134− ((string).pointer = (string).start, \
135− (string).end = (string).start+(size), \
136− memset((string).start, 0, (size)), \
137− 1) : \
138− ((context)->error = YAML_MEMORY_ERROR, \
139− 0))
140−
141−#define STRING_DEL(context,string) \
142− (yaml_free((string).start), \
143− (string).start = (string).pointer = (string).end = 0)
144−
145−#define STRING_EXTEND(context,string) \
146− ((((string).pointer+5 < (string).end) \
147− || yaml_string_extend(&(string).start, \
148− &(string).pointer, &(string).end)) ? \
149− 1 : \
150− ((context)->error = YAML_MEMORY_ERROR, \
151− 0))
152−
153−#define CLEAR(context,string) \
154− ((string).pointer = (string).start, \
155− memset((string).start, 0, (string).end-(string).start))
156−
157−#define JOIN(context,string_a,string_b) \
158− ((yaml_string_join(&(string_a).start, &(string_a).pointer, \
159− &(string_a).end, &(string_b).start, \
160− &(string_b).pointer, &(string_b).end)) ? \
161− ((string_b).pointer = (string_b).start, \
162− 1) : \
163− ((context)->error = YAML_MEMORY_ERROR, \
164− 0))
165−
166−/*
167− * String check operations.
168− */
169−
170−/*
171− * Check the octet at the specified position.
172− */
173−
174−#define CHECK_AT(string,octet,offset) \
175− ((string).pointer[offset] == (yaml_char_t)(octet))
176−
177−/*
178− * Check the current octet in the buffer.
179− */
180−
181−#define CHECK(string,octet) CHECK_AT((string),(octet),0)
182−
183−/*
184− * Check if the character at the specified position is an alphabetical
185− * character, a digit, '_', or '-'.
186− */
187−
188−#define IS_ALPHA_AT(string,offset) \
189− (((string).pointer[offset] >= (yaml_char_t) '0' && \
190− (string).pointer[offset] <= (yaml_char_t) '9') || \
191− ((string).pointer[offset] >= (yaml_char_t) 'A' && \
192− (string).pointer[offset] <= (yaml_char_t) 'Z') || \
193− ((string).pointer[offset] >= (yaml_char_t) 'a' && \
194− (string).pointer[offset] <= (yaml_char_t) 'z') || \
195− (string).pointer[offset] == '_' || \
196− (string).pointer[offset] == '-')
197−
198−#define IS_ALPHA(string) IS_ALPHA_AT((string),0)
199−
200−/*
201− * Check if the character at the specified position is a digit.
202− */
203−
204−#define IS_DIGIT_AT(string,offset) \
205− (((string).pointer[offset] >= (yaml_char_t) '0' && \
206− (string).pointer[offset] <= (yaml_char_t) '9'))
207−
208−#define IS_DIGIT(string) IS_DIGIT_AT((string),0)
209−
210−/*
211− * Get the value of a digit.
212− */
213−
214−#define AS_DIGIT_AT(string,offset) \
215− ((string).pointer[offset] - (yaml_char_t) '0')
216−
217−#define AS_DIGIT(string) AS_DIGIT_AT((string),0)
218−
219−/*
220− * Check if the character at the specified position is a hex-digit.
221− */
222−
223−#define IS_HEX_AT(string,offset) \
224− (((string).pointer[offset] >= (yaml_char_t) '0' && \
225− (string).pointer[offset] <= (yaml_char_t) '9') || \
226− ((string).pointer[offset] >= (yaml_char_t) 'A' && \
227− (string).pointer[offset] <= (yaml_char_t) 'F') || \
228− ((string).pointer[offset] >= (yaml_char_t) 'a' && \
229− (string).pointer[offset] <= (yaml_char_t) 'f'))
230−
231−#define IS_HEX(string) IS_HEX_AT((string),0)
232−
233−/*
234− * Get the value of a hex-digit.
235− */
236−
237−#define AS_HEX_AT(string,offset) \
238− (((string).pointer[offset] >= (yaml_char_t) 'A' && \
239− (string).pointer[offset] <= (yaml_char_t) 'F') ? \
240− ((string).pointer[offset] - (yaml_char_t) 'A' + 10) : \
241− ((string).pointer[offset] >= (yaml_char_t) 'a' && \
242− (string).pointer[offset] <= (yaml_char_t) 'f') ? \
243− ((string).pointer[offset] - (yaml_char_t) 'a' + 10) : \
244− ((string).pointer[offset] - (yaml_char_t) '0'))
245−
246−#define AS_HEX(string) AS_HEX_AT((string),0)
247−
248−/*
249− * Check if the character is ASCII.
250− */
251−
252−#define IS_ASCII_AT(string,offset) \
253− ((string).pointer[offset] <= (yaml_char_t) '\x7F')
254−
255−#define IS_ASCII(string) IS_ASCII_AT((string),0)
256−
257−/*
258− * Check if the character can be printed unescaped.
259− */
260−
261−#define IS_PRINTABLE_AT(string,offset) \
262− (((string).pointer[offset] == 0x0A) /* . == #x0A */ \
263− || ((string).pointer[offset] >= 0x20 /* #x20 <= . <= #x7E */ \
264− && (string).pointer[offset] <= 0x7E) \
265− || ((string).pointer[offset] == 0xC2 /* #0xA0 <= . <= #xD7FF */ \
266− && (string).pointer[offset+1] >= 0xA0) \
267− || ((string).pointer[offset] > 0xC2 \
268− && (string).pointer[offset] < 0xED) \
269− || ((string).pointer[offset] == 0xED \
270− && (string).pointer[offset+1] < 0xA0) \
271− || ((string).pointer[offset] == 0xEE) \
272− || ((string).pointer[offset] == 0xEF /* #xE000 <= . <= #xFFFD */ \
273− && !((string).pointer[offset+1] == 0xBB /* && . != #xFEFF */ \
274− && (string).pointer[offset+2] == 0xBF) \
275− && !((string).pointer[offset+1] == 0xBF \
276− && ((string).pointer[offset+2] == 0xBE \
277− || (string).pointer[offset+2] == 0xBF))))
278−
279−#define IS_PRINTABLE(string) IS_PRINTABLE_AT((string),0)
280−
281−/*
282− * Check if the character at the specified position is NUL.
283− */
284−
285−#define IS_Z_AT(string,offset) CHECK_AT((string),'\0',(offset))
286−
287−#define IS_Z(string) IS_Z_AT((string),0)
288−
289−/*
290− * Check if the character at the specified position is BOM.
291− */
292−
293−#define IS_BOM_AT(string,offset) \
294− (CHECK_AT((string),'\xEF',(offset)) \
295− && CHECK_AT((string),'\xBB',(offset)+1) \
296− && CHECK_AT((string),'\xBF',(offset)+2)) /* BOM (#xFEFF) */
297−
298−#define IS_BOM(string) IS_BOM_AT(string,0)
299−
300−/*
301− * Check if the character at the specified position is space.
302− */
303−
304−#define IS_SPACE_AT(string,offset) CHECK_AT((string),' ',(offset))
305−
306−#define IS_SPACE(string) IS_SPACE_AT((string),0)
307−
308−/*
309− * Check if the character at the specified position is tab.
310− */
311−
312−#define IS_TAB_AT(string,offset) CHECK_AT((string),'\t',(offset))
313−
314−#define IS_TAB(string) IS_TAB_AT((string),0)
315−
316−/*
317− * Check if the character at the specified position is blank (space or tab).
318− */
319−
320−#define IS_BLANK_AT(string,offset) \
321− (IS_SPACE_AT((string),(offset)) || IS_TAB_AT((string),(offset)))
322−
323−#define IS_BLANK(string) IS_BLANK_AT((string),0)
324−
325−/*
326− * Check if the character at the specified position is a line break.
327− */
328−
329−#define IS_BREAK_AT(string,offset) \
330− (CHECK_AT((string),'\r',(offset)) /* CR (#xD)*/ \
331− || CHECK_AT((string),'\n',(offset)) /* LF (#xA) */ \
332− || (CHECK_AT((string),'\xC2',(offset)) \
333− && CHECK_AT((string),'\x85',(offset)+1)) /* NEL (#x85) */ \
334− || (CHECK_AT((string),'\xE2',(offset)) \
335− && CHECK_AT((string),'\x80',(offset)+1) \
336− && CHECK_AT((string),'\xA8',(offset)+2)) /* LS (#x2028) */ \
337− || (CHECK_AT((string),'\xE2',(offset)) \
338− && CHECK_AT((string),'\x80',(offset)+1) \
339− && CHECK_AT((string),'\xA9',(offset)+2))) /* PS (#x2029) */
340−
341−#define IS_BREAK(string) IS_BREAK_AT((string),0)
342−
343−#define IS_CRLF_AT(string,offset) \
344− (CHECK_AT((string),'\r',(offset)) && CHECK_AT((string),'\n',(offset)+1))
345−
346−#define IS_CRLF(string) IS_CRLF_AT((string),0)
347−
348−/*
349− * Check if the character is a line break or NUL.
350− */
351−
352−#define IS_BREAKZ_AT(string,offset) \
353− (IS_BREAK_AT((string),(offset)) || IS_Z_AT((string),(offset)))
354−
355−#define IS_BREAKZ(string) IS_BREAKZ_AT((string),0)
356−
357−/*
358− * Check if the character is a line break, space, or NUL.
359− */
360−
361−#define IS_SPACEZ_AT(string,offset) \
362− (IS_SPACE_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset)))
363−
364−#define IS_SPACEZ(string) IS_SPACEZ_AT((string),0)
365−
366−/*
367− * Check if the character is a line break, space, tab, or NUL.
368− */
369−
370−#define IS_BLANKZ_AT(string,offset) \
371− (IS_BLANK_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset)))
372−
373−#define IS_BLANKZ(string) IS_BLANKZ_AT((string),0)
374−
375−/*
376− * Determine the width of the character.
377− */
378−
379−#define WIDTH_AT(string,offset) \
380− (((string).pointer[offset] & 0x80) == 0x00 ? 1 : \
381− ((string).pointer[offset] & 0xE0) == 0xC0 ? 2 : \
382− ((string).pointer[offset] & 0xF0) == 0xE0 ? 3 : \
383− ((string).pointer[offset] & 0xF8) == 0xF0 ? 4 : 0)
384−
385−#define WIDTH(string) WIDTH_AT((string),0)
386−
387−/*
388− * Move the string pointer to the next character.
389− */
390−
391−#define MOVE(string) ((string).pointer += WIDTH((string)))
392−
393−/*
394− * Copy a character and move the pointers of both strings.
395− */
396−
397−#define COPY(string_a,string_b) \
398− ((*(string_b).pointer & 0x80) == 0x00 ? \
399− (*((string_a).pointer++) = *((string_b).pointer++)) : \
400− (*(string_b).pointer & 0xE0) == 0xC0 ? \
401− (*((string_a).pointer++) = *((string_b).pointer++), \
402− *((string_a).pointer++) = *((string_b).pointer++)) : \
403− (*(string_b).pointer & 0xF0) == 0xE0 ? \
404− (*((string_a).pointer++) = *((string_b).pointer++), \
405− *((string_a).pointer++) = *((string_b).pointer++), \
406− *((string_a).pointer++) = *((string_b).pointer++)) : \
407− (*(string_b).pointer & 0xF8) == 0xF0 ? \
408− (*((string_a).pointer++) = *((string_b).pointer++), \
409− *((string_a).pointer++) = *((string_b).pointer++), \
410− *((string_a).pointer++) = *((string_b).pointer++), \
411− *((string_a).pointer++) = *((string_b).pointer++)) : 0)
412−
413−/*
414− * Stack and queue management.
415− */
416−
417−YAML_DECLARE(int)
418−yaml_stack_extend(void **start, void **top, void **end);
419−
420−YAML_DECLARE(int)
421−yaml_queue_extend(void **start, void **head, void **tail, void **end);
422−
423−#define STACK_INIT(context,stack,type) \
424− (((stack).start = (type)yaml_malloc(INITIAL_STACK_SIZE*sizeof(*(stack).start))) ? \
425− ((stack).top = (stack).start, \
426− (stack).end = (stack).start+INITIAL_STACK_SIZE, \
427− 1) : \
428− ((context)->error = YAML_MEMORY_ERROR, \
429− 0))
430−
431−#define STACK_DEL(context,stack) \
432− (yaml_free((stack).start), \
433− (stack).start = (stack).top = (stack).end = 0)
434−
435−#define STACK_EMPTY(context,stack) \
436− ((stack).start == (stack).top)
437−
438−#define STACK_LIMIT(context,stack,size) \
439− ((stack).top - (stack).start < (size) ? \
440− 1 : \
441− ((context)->error = YAML_MEMORY_ERROR, \
442− 0))
443−
444−#define PUSH(context,stack,value) \
445− (((stack).top != (stack).end \
446− || yaml_stack_extend((void **)&(stack).start, \
447− (void **)&(stack).top, (void **)&(stack).end)) ? \
448− (*((stack).top++) = value, \
449− 1) : \
450− ((context)->error = YAML_MEMORY_ERROR, \
451− 0))
452−
453−#define POP(context,stack) \
454− (*(--(stack).top))
455−
456−#define QUEUE_INIT(context,queue,size,type) \
457− (((queue).start = (type)yaml_malloc((size)*sizeof(*(queue).start))) ? \
458− ((queue).head = (queue).tail = (queue).start, \
459− (queue).end = (queue).start+(size), \
460− 1) : \
461− ((context)->error = YAML_MEMORY_ERROR, \
462− 0))
463−
464−#define QUEUE_DEL(context,queue) \
465− (yaml_free((queue).start), \
466− (queue).start = (queue).head = (queue).tail = (queue).end = 0)
467−
468−#define QUEUE_EMPTY(context,queue) \
469− ((queue).head == (queue).tail)
470−
471−#define ENQUEUE(context,queue,value) \
472− (((queue).tail != (queue).end \
473− || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
474− (void **)&(queue).tail, (void **)&(queue).end)) ? \
475− (*((queue).tail++) = value, \
476− 1) : \
477− ((context)->error = YAML_MEMORY_ERROR, \
478− 0))
479−
480−#define DEQUEUE(context,queue) \
481− (*((queue).head++))
482−
483−#define QUEUE_INSERT(context,queue,index,value) \
484− (((queue).tail != (queue).end \
485− || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
486− (void **)&(queue).tail, (void **)&(queue).end)) ? \
487− (memmove((queue).head+(index)+1,(queue).head+(index), \
488− ((queue).tail-(queue).head-(index))*sizeof(*(queue).start)), \
489− *((queue).head+(index)) = value, \
490− (queue).tail++, \
491− 1) : \
492− ((context)->error = YAML_MEMORY_ERROR, \
493− 0))
494−
495−/*
496− * Token initializers.
497− */
498−
499−#define TOKEN_INIT(token,token_type,token_start_mark,token_end_mark) \
500− (memset(&(token), 0, sizeof(yaml_token_t)), \
501− (token).type = (token_type), \
502− (token).start_mark = (token_start_mark), \
503− (token).end_mark = (token_end_mark))
504−
505−#define STREAM_START_TOKEN_INIT(token,token_encoding,start_mark,end_mark) \
506− (TOKEN_INIT((token),YAML_STREAM_START_TOKEN,(start_mark),(end_mark)), \
507− (token).data.stream_start.encoding = (token_encoding))
508−
509−#define STREAM_END_TOKEN_INIT(token,start_mark,end_mark) \
510− (TOKEN_INIT((token),YAML_STREAM_END_TOKEN,(start_mark),(end_mark)))
511−
512−#define ALIAS_TOKEN_INIT(token,token_value,start_mark,end_mark) \
513− (TOKEN_INIT((token),YAML_ALIAS_TOKEN,(start_mark),(end_mark)), \
514− (token).data.alias.value = (token_value))
515−
516−#define ANCHOR_TOKEN_INIT(token,token_value,start_mark,end_mark) \
517− (TOKEN_INIT((token),YAML_ANCHOR_TOKEN,(start_mark),(end_mark)), \
518− (token).data.anchor.value = (token_value))
519−
520−#define TAG_TOKEN_INIT(token,token_handle,token_suffix,start_mark,end_mark) \
521− (TOKEN_INIT((token),YAML_TAG_TOKEN,(start_mark),(end_mark)), \
522− (token).data.tag.handle = (token_handle), \
523− (token).data.tag.suffix = (token_suffix))
524−
525−#define SCALAR_TOKEN_INIT(token,token_value,token_length,token_style,start_mark,end_mark) \
526− (TOKEN_INIT((token),YAML_SCALAR_TOKEN,(start_mark),(end_mark)), \
527− (token).data.scalar.value = (token_value), \
528− (token).data.scalar.length = (token_length), \
529− (token).data.scalar.style = (token_style))
530−
531−#define VERSION_DIRECTIVE_TOKEN_INIT(token,token_major,token_minor,start_mark,end_mark) \
532− (TOKEN_INIT((token),YAML_VERSION_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
533− (token).data.version_directive.major = (token_major), \
534− (token).data.version_directive.minor = (token_minor))
535−
536−#define TAG_DIRECTIVE_TOKEN_INIT(token,token_handle,token_prefix,start_mark,end_mark) \
537− (TOKEN_INIT((token),YAML_TAG_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
538− (token).data.tag_directive.handle = (token_handle), \
539− (token).data.tag_directive.prefix = (token_prefix))
540−
541−/*
542− * Event initializers.
543− */
544−
545−#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark) \
546− (memset(&(event), 0, sizeof(yaml_event_t)), \
547− (event).type = (event_type), \
548− (event).start_mark = (event_start_mark), \
549− (event).end_mark = (event_end_mark))
550−
551−#define STREAM_START_EVENT_INIT(event,event_encoding,start_mark,end_mark) \
552− (EVENT_INIT((event),YAML_STREAM_START_EVENT,(start_mark),(end_mark)), \
553− (event).data.stream_start.encoding = (event_encoding))
554−
555−#define STREAM_END_EVENT_INIT(event,start_mark,end_mark) \
556− (EVENT_INIT((event),YAML_STREAM_END_EVENT,(start_mark),(end_mark)))
557−
558−#define DOCUMENT_START_EVENT_INIT(event,event_version_directive, \
559− event_tag_directives_start,event_tag_directives_end,event_implicit,start_mark,end_mark) \
560− (EVENT_INIT((event),YAML_DOCUMENT_START_EVENT,(start_mark),(end_mark)), \
561− (event).data.document_start.version_directive = (event_version_directive), \
562− (event).data.document_start.tag_directives.start = (event_tag_directives_start), \
563− (event).data.document_start.tag_directives.end = (event_tag_directives_end), \
564− (event).data.document_start.implicit = (event_implicit))
565−
566−#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \
567− (EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \
568− (event).data.document_end.implicit = (event_implicit))
569−
570−#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark) \
571− (EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)), \
572− (event).data.alias.anchor = (event_anchor))
573−
574−#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length, \
575− event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark) \
576− (EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)), \
577− (event).data.scalar.anchor = (event_anchor), \
578− (event).data.scalar.tag = (event_tag), \
579− (event).data.scalar.value = (event_value), \
580− (event).data.scalar.length = (event_length), \
581− (event).data.scalar.plain_implicit = (event_plain_implicit), \
582− (event).data.scalar.quoted_implicit = (event_quoted_implicit), \
583− (event).data.scalar.style = (event_style))
584−
585−#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag, \
586− event_implicit,event_style,start_mark,end_mark) \
587− (EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)), \
588− (event).data.sequence_start.anchor = (event_anchor), \
589− (event).data.sequence_start.tag = (event_tag), \
590− (event).data.sequence_start.implicit = (event_implicit), \
591− (event).data.sequence_start.style = (event_style))
592−
593−#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark) \
594− (EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark)))
595−
596−#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag, \
597− event_implicit,event_style,start_mark,end_mark) \
598− (EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)), \
599− (event).data.mapping_start.anchor = (event_anchor), \
600− (event).data.mapping_start.tag = (event_tag), \
601− (event).data.mapping_start.implicit = (event_implicit), \
602− (event).data.mapping_start.style = (event_style))
603−
604−#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \
605− (EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark)))
606−
607−/*
608− * Document initializer.
609− */
610−
611−#define DOCUMENT_INIT(document,document_nodes_start,document_nodes_end, \
612− document_version_directive,document_tag_directives_start, \
613− document_tag_directives_end,document_start_implicit, \
614− document_end_implicit,document_start_mark,document_end_mark) \
615− (memset(&(document), 0, sizeof(yaml_document_t)), \
616− (document).nodes.start = (document_nodes_start), \
617− (document).nodes.end = (document_nodes_end), \
618− (document).nodes.top = (document_nodes_start), \
619− (document).version_directive = (document_version_directive), \
620− (document).tag_directives.start = (document_tag_directives_start), \
621− (document).tag_directives.end = (document_tag_directives_end), \
622− (document).start_implicit = (document_start_implicit), \
623− (document).end_implicit = (document_end_implicit), \
624− (document).start_mark = (document_start_mark), \
625− (document).end_mark = (document_end_mark))
626−
627−/*
628− * Node initializers.
629− */
630−
631−#define NODE_INIT(node,node_type,node_tag,node_start_mark,node_end_mark) \
632− (memset(&(node), 0, sizeof(yaml_node_t)), \
633− (node).type = (node_type), \
634− (node).tag = (node_tag), \
635− (node).start_mark = (node_start_mark), \
636− (node).end_mark = (node_end_mark))
637−
638−#define SCALAR_NODE_INIT(node,node_tag,node_value,node_length, \
639− node_style,start_mark,end_mark) \
640− (NODE_INIT((node),YAML_SCALAR_NODE,(node_tag),(start_mark),(end_mark)), \
641− (node).data.scalar.value = (node_value), \
642− (node).data.scalar.length = (node_length), \
643− (node).data.scalar.style = (node_style))
644−
645−#define SEQUENCE_NODE_INIT(node,node_tag,node_items_start,node_items_end, \
646− node_style,start_mark,end_mark) \
647− (NODE_INIT((node),YAML_SEQUENCE_NODE,(node_tag),(start_mark),(end_mark)), \
648− (node).data.sequence.items.start = (node_items_start), \
649− (node).data.sequence.items.end = (node_items_end), \
650− (node).data.sequence.items.top = (node_items_start), \
651− (node).data.sequence.style = (node_style))
652−
653−#define MAPPING_NODE_INIT(node,node_tag,node_pairs_start,node_pairs_end, \
654− node_style,start_mark,end_mark) \
655− (NODE_INIT((node),YAML_MAPPING_NODE,(node_tag),(start_mark),(end_mark)), \
656− (node).data.mapping.pairs.start = (node_pairs_start), \
657− (node).data.mapping.pairs.end = (node_pairs_end), \
658− (node).data.mapping.pairs.top = (node_pairs_start), \
659− (node).data.mapping.style = (node_style))
660−
661−/* Strict C compiler warning helpers */
662−
663−#if defined(__clang__) || defined(__GNUC__)
664−# define HASATTRIBUTE_UNUSED
665−#endif
666−#ifdef HASATTRIBUTE_UNUSED
667−# define __attribute__unused__ __attribute__((__unused__))
668−#else
669−# define __attribute__unused__
670−#endif
671−
672−/* Shim arguments are arguments that must be included in your function,
673− * but serve no purpose inside. Silence compiler warnings. */
674−#define SHIM(a) /*@unused@*/ a __attribute__unused__
675−
676−/* UNUSED_PARAM() marks a shim argument in the body to silence compiler warnings */
677−#ifdef __clang__
678−# define UNUSED_PARAM(a) (void)(a);
679−#else
680−# define UNUSED_PARAM(a) /*@-noeffect*/if (0) (void)(a)/*@=noeffect*/;
681−#endif
682−
683−#define YAML_MALLOC_STATIC(type) (type*)yaml_malloc(sizeof(type))
684−#define YAML_MALLOC(size) (yaml_char_t *)yaml_malloc(size)
685−
686−/* For Haskell yaml package, since we do not use the configure script */
687−#define YAML_VERSION_STRING "0.2.1"
688−#define YAML_VERSION_MAJOR 0
689−#define YAML_VERSION_MINOR 2
690−#define YAML_VERSION_PATCH 1
stack.yaml+8−1
@@ -1,5 +1,12 @@
1−resolver: lts-11.10
1+resolver: lts-22.13
2
2
3flags:
3flags:
4 yaml:
4 yaml:
5 no-examples: false
5 no-examples: false
6+
7+packages:
8+ - yaml
9+ - libyaml
10+
11+extra-deps:
12+ - libyaml-clib-0.2.5
vendor/libyamldeleted−1

Submodule changed.

ChangeLog.md → yaml/ChangeLog.mdrenamed+84
@@ -1,5 +1,89 @@
1# ChangeLog for yaml
1# ChangeLog for yaml
2
2
3+## 0.11.11.2
4+
5+* Compat with aeson 2.2
6+
7+## 0.11.11.1
8+
9+* For optparse-applicative-0.18: use `pretty` instead of `text` [#216](https://github.com/snoyberg/yaml/pull/216)
10+
11+## 0.11.11.0
12+
13+* Fix ambiguous occurrence `AesonException`
14+
15+## 0.11.10.0
16+
17+* Undo previous change (breakage with aeson 2)
18+
19+## 0.11.9.0
20+
21+* Data.Yaml.Pretty: provide key-sorting function with path to parent object [#206](https://github.com/snoyberg/yaml/pull/206)
22+
23+## 0.11.8.0
24+
25+* Export `Parse` and `StringStyle` [#204](https://github.com/snoyberg/yaml/pull/204)
26+
27+## 0.11.7.0
28+
29+* Support `aeson` 2 [#202](https://github.com/snoyberg/yaml/pull/202)
30+
31+## 0.11.6.0
32+
33+* `yaml2json`: add `--help` and `--version` options [#197](https://github.com/snoyberg/yaml/pull/197)
34+* `json2yaml`: add `--help` and `--version` options [#198](https://github.com/snoyberg/yaml/pull/198)
35+* Add the `-o` options to both `yaml2json` and `json2yaml` [#200](https://github.com/snoyberg/yaml/pull/200)
36+
37+## 0.11.5.0
38+
39+* New functions capable of parsing YAML streams containing multiple documents into a list of results:
40+ * `decodeAllEither'`
41+ * `decodeAllFileEither`
42+ * `decodeAllFileWithWarnings`
43+ * `decodeAllThrow`
44+ * `decodeAllFileThrow`
45+
46+## 0.11.4.0
47+
48+* add `ToYaml` instance for `String` [#186](https://github.com/snoyberg/yaml/pull/186)
49+
50+## 0.11.3.0
51+
52+* Don't wrap up async exceptions [#185](https://github.com/snoyberg/yaml/issues/185)
53+
54+## 0.11.2.0
55+
56+* Reduces some of the code duplication between the `encode` and `encodePretty` functions
57+* The output of `encodePretty` has been improved:
58+ - Multiline strings now use `Literal` style instead of `SingleQuoted`
59+ - Special keys are now quoted in mappings [#179](https://github.com/snoyberg/yaml/issues/179)
60+* Support for complex keys in mappings: [#182](https://github.com/snoyberg/yaml/issues/182)
61+ - Adds `complexMapping` function to `Data.Yaml.Builder`
62+ - Decode functions now return a `NonStringKey` error when attempting to decode a mapping with a complex key as it is not possible to decode these to an Aeson `Value`
63+* Adds missing `ToYaml` instances
64+
65+## 0.11.1.2
66+
67+* Compiles with GHC 8.8.1 (`MonadFail` split)
68+
69+## 0.11.1.1
70+
71+* Use the appropriate `Scientific` rendering function to avoid a memory overflow when rendering. The previously used function from `aeson` would not use scientific notation, and could use large amounts of memory for values such as `1e9999999999999`.
72+
73+## 0.11.1.0
74+
75+* Better error messages in the `Data.Yaml.Config` module [#168](https://github.com/snoyberg/yaml/issues/168)
76+* Add `LoadSettingsException` exception and remove error printing from `loadYamlSettings` [#172](https://github.com/snoyberg/yaml/pull/172)
77+
78+## 0.11.0.0
79+
80+* Split out the `libyaml` and `Text.Libyaml` code into its own package. [#145](https://github.com/snoyberg/yaml/issues/145)
81+
82+## 0.10.4.0
83+
84+* Add `decodeMarked` and `decodeFileMarked` functions to `Text.Libyaml`, and
85+ extend native bindings to extract mark information. [#157](https://github.com/snoyberg/yaml/issues/157)
86+
3## 0.10.3.0
87## 0.10.3.0
4
88
5* Add support for anchors and aliases to Data.Yaml.Builder [#155](https://github.com/snoyberg/yaml/pull/155)
89* Add support for anchors and aliases to Data.Yaml.Builder [#155](https://github.com/snoyberg/yaml/pull/155)
LICENSE → yaml/LICENSErenamed

The content is the same.

yaml/README.mdnew file+26
@@ -0,0 +1,26 @@
1+## yaml
2+
3+[![GitHub build and test status](https://github.com/snoyberg/yaml/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/snoyberg/yaml/actions/workflows/tests.yml)
4+[![Appveyor build status](https://ci.appveyor.com/api/projects/status/hqy2jketp8m502so/branch/master?svg=true)](https://ci.appveyor.com/project/snoyberg/yaml/branch/master)
5+
6+Provides support for parsing and emitting Yaml documents.
7+
8+`Data.Yaml` provides a high-level interface based around the JSON datatypes provided by the `aeson` package. It uses `Text.Libyaml` from `libyaml` in its implementation of the low-level yaml encoder/decoder.
9+
10+### Examples
11+
12+Usage examples can be found in the `Data.Yaml` documentation or in the [examples](https://github.com/snoyberg/yaml/tree/master/yaml/examples) directory.
13+
14+### Additional `yaml` modules
15+
16+* `Data.Yaml.Include` supports adding `!include` directives to your YAML files.
17+* `Data.Yaml.Builder` and `Data.Yaml.Parser` allow more fine-grained control of parsing an rendering, as opposed to just using the aeson typeclass and datatype system for parsing and rendering.
18+* `Data.Yaml.Aeson` is currently a re-export of `Data.Yaml` to explicitly choose to use the aeson-compatible API.
19+
20+### Executables
21+
22+Converters `json2yaml` and `yaml2json` can be built by disabling flag `no-exe`, e.g., one of:
23+```
24+cabal install yaml -f-no-exe
25+stack install yaml --flag yaml:-no-exe
26+```
Setup.lhs → yaml/Setup.lhsrenamed

The content is the same.

builder-test.hs → yaml/builder-test.hsrenamed

The content is the same.

examples/Config.hs → yaml/examples/Config.hsrenamed

The content is the same.

examples/Main.hs → yaml/examples/Main.hsrenamed

The content is the same.

examples/Simple.hs → yaml/examples/Simple.hsrenamed

The content is the same.

yaml/exe/Common.hsnew file+68
@@ -0,0 +1,68 @@
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE LambdaCase #-}
3+
4+-- | Code shared between @yaml2json@ and @json2yaml@.
5+
6+module Common where
7+
8+import Data.List ( intercalate )
9+#if !MIN_VERSION_base(4,11,0)
10+import Data.Semigroup ( Semigroup(..) )
11+#endif
12+import Data.Version ( Version(versionBranch) )
13+
14+import Options.Applicative ( Parser, help, hidden, infoOption, long, short )
15+
16+import qualified Paths_yaml as Paths
17+
18+-- * Version info and option
19+---------------------------------------------------------------------------
20+
21+-- | Homepage for @yaml2json@ and @json2yaml@.
22+
23+homepage :: String
24+homepage = "https://github.com/snoyberg/yaml/"
25+
26+-- | Version in @x.y.z@ format.
27+
28+version :: String
29+version = intercalate "." $ map show $ versionBranch Paths.version
30+
31+-- | The version header including given program name and 'homepage'.
32+
33+versionText :: String -> String
34+versionText self = unwords
35+ [ self
36+ , "version"
37+ , version
38+ , homepage -- concat [ "<", homepage, ">" ]
39+ ]
40+
41+-- | Option @--numeric-version@.
42+
43+numericVersionOption :: Parser (a -> a)
44+numericVersionOption =
45+ infoOption version
46+ $ long "numeric-version"
47+ <> hidden
48+ <> help "Show just version number."
49+
50+-- | Option @--version@.
51+
52+versionOption :: String -> Parser (a -> a)
53+versionOption self =
54+ infoOption (versionText self)
55+ $ long "version"
56+ <> short 'V'
57+ <> hidden
58+ <> help "Show version info."
59+
60+-- * Misc
61+---------------------------------------------------------------------------
62+
63+-- | @Just@ unless argument is @"-"@ (denoting @stdin@ or @stdout@).
64+
65+dashToNothing :: FilePath -> Maybe FilePath
66+dashToNothing = \case
67+ "-" -> Nothing
68+ file -> Just file
yaml/exe/json2yaml.hsnew file+106
@@ -0,0 +1,106 @@
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE NamedFieldPuns #-}
3+
4+import qualified Data.Aeson as J
5+import qualified Data.ByteString as S
6+import qualified Data.ByteString.Lazy as L
7+import qualified Data.Yaml as Y
8+#if !MIN_VERSION_base(4,11,0)
9+import Data.Semigroup ( Semigroup(..) )
10+#endif
11+
12+import Options.Applicative
13+ ( Parser, (<|>)
14+ , action, execParser, footerDoc, headerDoc, help, helper, hidden, info
15+ , long, metavar, short, strArgument, strOption, value
16+ )
17+import Options.Applicative.Help.Pretty
18+ ( vcat, pretty )
19+
20+import System.Exit ( die )
21+
22+import Common ( dashToNothing, versionText, versionOption, numericVersionOption )
23+
24+data Options = Options
25+ { optInput :: Maybe FilePath
26+ -- ^ 'Nothing' means @stdin@.
27+ , optOutput :: Maybe FilePath
28+ -- ^ 'Nothing' means @stdout@.
29+ }
30+
31+-- | Name of the executable.
32+
33+self :: String
34+self = "json2yaml"
35+
36+-- | Parse options; handle parse errors, @--help@, @--version@.
37+
38+options :: IO Options
39+options =
40+ execParser $
41+ info (helper <*> versionOption self <*> numericVersionOption <*> programOptions)
42+ $ headerDoc hdoc
43+ <> footerDoc fdoc
44+
45+ where
46+ hdoc = Just $ vcat $ map pretty
47+ [ versionText self
48+ , "Convert JSON to YAML."
49+ ]
50+ fdoc = Just $ pretty $ concat
51+ [ "The old call pattern '"
52+ , self
53+ , " IN OUT' is also accepted, but deprecated."
54+ ]
55+
56+ programOptions :: Parser Options
57+ programOptions = Options <$> oInput <*> oOutput
58+
59+ oInput :: Parser (Maybe FilePath)
60+ oInput = dashToNothing <$> do
61+ strArgument
62+ $ metavar "IN"
63+ <> value "-"
64+ <> action "file"
65+ <> help "The input file containing the JSON document; use '-' for stdin (default)."
66+
67+ oOutput :: Parser (Maybe FilePath)
68+ oOutput = dashToNothing <$> do
69+ oOutputExplicit <|> oOutputImplicit
70+
71+ oOutputExplicit :: Parser FilePath
72+ oOutputExplicit =
73+ strOption
74+ $ long "output"
75+ <> short 'o'
76+ <> metavar "OUT"
77+ <> action "file"
78+ -- <> help "The file to hold the produced YAML document; use '-' for stdout (default)."
79+
80+ oOutputImplicit :: Parser FilePath
81+ oOutputImplicit =
82+ strArgument
83+ $ metavar "OUT"
84+ <> value "-"
85+ <> action "file"
86+ <> hidden
87+ <> help "The file to hold the produced YAML document; use '-' for stdout (default)."
88+
89+-- | Exit with 'self'-stamped error message.
90+
91+abort :: String -> IO a
92+abort msg = die $ concat [ self, ": ", msg ]
93+
94+main :: IO ()
95+main = do
96+ Options{ optInput, optOutput } <- options
97+
98+ -- Read JSON.
99+ mval <- J.decode <$> maybe L.getContents L.readFile optInput
100+
101+ -- Write YAML.
102+ case mval of
103+ Nothing -> abort "Invalid input JSON"
104+ Just val -> case optOutput of
105+ Nothing -> S.putStr $ Y.encode (val :: Y.Value)
106+ Just f -> Y.encodeFile f val
yaml/exe/yaml2json.hsnew file+87
@@ -0,0 +1,87 @@
1+{-# LANGUAGE CPP #-}
2+{-# LANGUAGE LambdaCase #-}
3+{-# LANGUAGE NamedFieldPuns #-}
4+
5+import Data.Aeson (encode, Value)
6+import qualified Data.ByteString as S (getContents)
7+import qualified Data.ByteString.Lazy as L (putStr, writeFile)
8+#if !MIN_VERSION_base(4,11,0)
9+import Data.Semigroup (Semigroup(..))
10+#endif
11+import Data.Yaml (decodeFileEither, decodeEither')
12+import System.Exit (die)
13+
14+import Options.Applicative
15+ ( Parser
16+ , action, execParser, headerDoc, help, helper, info
17+ , long, metavar, short, strArgument, strOption, value
18+ )
19+import Options.Applicative.Help.Pretty
20+ ( vcat, pretty )
21+
22+import Common
23+ ( versionText, versionOption, numericVersionOption, dashToNothing )
24+
25+data Options = Options
26+ { optInput :: Maybe FilePath
27+ -- ^ 'Nothing' means @stdin@.
28+ , optOutput :: Maybe FilePath
29+ -- ^ 'Nothing' means @stdout@.
30+ }
31+
32+-- | Name of the executable.
33+
34+self :: String
35+self = "yaml2json"
36+
37+-- | Parse options; handle parse errors, @--help@, @--version@.
38+
39+options :: IO Options
40+options =
41+ execParser $
42+ info (helper <*> versionOption self <*> numericVersionOption <*> programOptions)
43+ (headerDoc hdoc)
44+
45+ where
46+ hdoc = Just $ vcat $ map pretty
47+ [ versionText self
48+ , "Convert YAML to JSON."
49+ ]
50+
51+ programOptions = Options <$> oInput <*> oOutput
52+
53+ oInput :: Parser (Maybe FilePath)
54+ oInput = dashToNothing <$> do
55+ strArgument
56+ $ metavar "IN"
57+ <> value "-"
58+ <> action "file"
59+ <> help "The input file containing the YAML document; use '-' for stdin (default)."
60+
61+ oOutput :: Parser (Maybe FilePath)
62+ oOutput = dashToNothing <$> do
63+ strOption
64+ $ long "output"
65+ <> short 'o'
66+ <> value "-"
67+ <> metavar "OUT"
68+ <> action "file"
69+ <> help "The file to hold the produced JSON document; use '-' for stdout (default)."
70+
71+
72+main :: IO ()
73+main = do
74+ Options{ optInput, optOutput } <- options
75+
76+ -- Input YAML.
77+ result <- case optInput of
78+ -- strict getContents will read in all of stdin at once
79+ Nothing -> decodeEither' <$> S.getContents
80+ Just f -> decodeFileEither f
81+
82+ -- Output JSON.
83+ case result of
84+ Left err -> die $ show err
85+ Right val -> do
86+ let json = encode (val :: Value)
87+ maybe L.putStr L.writeFile optOutput json
package.yaml → yaml/package.yamlrenamed+16−46
@@ -1,5 +1,5 @@
1name: yaml
1name: yaml
2−version: 0.10.3.0
2+version: 0.11.11.2
3synopsis: Support for parsing and rendering YAML documents.
3synopsis: Support for parsing and rendering YAML documents.
4description: README and API documentation are available at <https://www.stackage.org/package/yaml>
4description: README and API documentation are available at <https://www.stackage.org/package/yaml>
5category: Data
5category: Data
@@ -10,10 +10,6 @@ github: snoyberg/yaml
10stability: stable
10stability: stable
11
11
12extra-source-files:
12extra-source-files:
13−- c/helper.h
14−- libyaml/yaml_private.h
15−- libyaml/yaml.h
16−- libyaml/LICENSE
17- test/largest-string.yaml
13- test/largest-string.yaml
18- test/json.yaml
14- test/json.yaml
19- test/resources/foo.yaml
15- test/resources/foo.yaml
@@ -36,71 +32,39 @@ flags:
36 description: don't build the examples
32 description: don't build the examples
37 manual: false
33 manual: false
38 default: true
34 default: true
39− system-libyaml:
40− description: Use the system-wide libyaml instead of the bundled copy
41− manual: false
42− default: false
43− no-unicode:
44− description: Don't enable unicode output. Instead, unicode characters will be escaped.
45− manual: false
46− default: false
47
35
48dependencies:
36dependencies:
49−- base >=4.9.1 && <5 # GHC 8.0.2 and later
37+- base >=4.14 && <5 # GHC 8.10.1 and later
50- bytestring >=0.9.1.4
38- bytestring >=0.9.1.4
51- transformers >=0.1
39- transformers >=0.1
52- mtl
40- mtl
53- conduit >=1.2.8 && <1.4
41- conduit >=1.2.8 && <1.4
54−- resourcet >=0.3 && <1.3
42+- resourcet >=0.3 && <1.4
55- aeson >=0.11
43- aeson >=0.11
56- containers
44- containers
57- unordered-containers
45- unordered-containers
58- vector
46- vector
59- text
47- text
60- attoparsec >=0.11.3.0
48- attoparsec >=0.11.3.0
61−- scientific
49+- scientific >= 0.3 # for Data.ByteString.Builder.Scientific
62- filepath
50- filepath
63- directory
51- directory
64- template-haskell
52- template-haskell
65−when:
53+- libyaml >=0.1 && <0.2
66− condition: "!impl(ghc >= 8.0)"
54+
67− dependencies:
55+ghc-options: -Wall -Wcompat
68− - semigroups
69
56
70library:
57library:
71− c-sources: c/helper.c
72 other-extensions:
58 other-extensions:
73 - LambdaCase
59 - LambdaCase
74− ghc-options: -Wall
75− include-dirs:
76− - c
77 source-dirs: src
60 source-dirs: src
78− when:
79− - condition: flag(no-unicode)
80− cpp-options: -D__NO_UNICODE__
81− - condition: ! '!(flag(system-libyaml))'
82− then:
83− c-sources:
84− - libyaml/api.c
85− - libyaml/dumper.c
86− - libyaml/emitter.c
87− - libyaml/loader.c
88− - libyaml/parser.c
89− - libyaml/reader.c
90− - libyaml/scanner.c
91− - libyaml/writer.c
92− include-dirs:
93− - libyaml
94− else:
95− extra-libraries: yaml
96− - condition: os(windows)
97− cpp-options: -DWINDOWS
98
61
99executables:
62executables:
100 json2yaml:
63 json2yaml:
101 main: json2yaml.hs
64 main: json2yaml.hs
102 source-dirs: exe
65 source-dirs: exe
103 dependencies:
66 dependencies:
67+ - optparse-applicative
104 - yaml
68 - yaml
105 when:
69 when:
106 - condition: flag(no-exe)
70 - condition: flag(no-exe)
@@ -109,14 +73,18 @@ executables:
109 main: yaml2json.hs
73 main: yaml2json.hs
110 source-dirs: exe
74 source-dirs: exe
111 dependencies:
75 dependencies:
76+ - optparse-applicative
112 - yaml
77 - yaml
113 when:
78 when:
114 - condition: flag(no-exe)
79 - condition: flag(no-exe)
115 buildable: false
80 buildable: false
81+ other-extensions:
82+ - CPP
83+ - LambdaCase
84+ - NamedFieldPuns
116 examples:
85 examples:
117 main: Main.hs
86 main: Main.hs
118 source-dirs: examples
87 source-dirs: examples
119− ghc-options: -Wall
120 when:
88 when:
121 - condition: flag(no-examples)
89 - condition: flag(no-examples)
122 then:
90 then:
@@ -130,7 +98,7 @@ tests:
130 spec:
98 spec:
131 main: Spec.hs
99 main: Spec.hs
132 source-dirs: test
100 source-dirs: test
133− ghc-options: -Wall "-with-rtsopts=-K1K"
101+ ghc-options: "-with-rtsopts=-K1K"
134 cpp-options: -DTEST
102 cpp-options: -DTEST
135 dependencies:
103 dependencies:
136 - hspec >=1.3
104 - hspec >=1.3
@@ -141,3 +109,5 @@ tests:
141 - base-compat
109 - base-compat
142 - temporary
110 - temporary
143 - raw-strings-qq
111 - raw-strings-qq
112+ build-tools:
113+ - hspec-discover
parser-test.hs → yaml/parser-test.hsrenamed

The content is the same.

src/Data/Yaml.hs → yaml/src/Data/Yaml.hsrenamed+64−72
@@ -37,6 +37,16 @@ module Data.Yaml
37 , decodeFileWithWarnings
37 , decodeFileWithWarnings
38 , decodeThrow
38 , decodeThrow
39 , decodeFileThrow
39 , decodeFileThrow
40+ -- ** Decoding multiple documents
41+ --
42+ -- | For situations where we need to be able to parse multiple documents
43+ -- separated by `---` in a YAML stream, these functions decode a list of
44+ -- values rather than a single value.
45+ , decodeAllEither'
46+ , decodeAllFileEither
47+ , decodeAllFileWithWarnings
48+ , decodeAllThrow
49+ , decodeAllFileThrow
40 -- ** More control over decoding
50 -- ** More control over decoding
41 , decodeHelper
51 , decodeHelper
42 -- * Types
52 -- * Types
@@ -72,6 +82,7 @@ module Data.Yaml
72 , isSpecialString
82 , isSpecialString
73 , EncodeOptions
83 , EncodeOptions
74 , defaultEncodeOptions
84 , defaultEncodeOptions
85+ , defaultStringStyle
75 , setStringStyle
86 , setStringStyle
76 , setFormat
87 , setFormat
77 , FormatOptions
88 , FormatOptions
@@ -94,22 +105,10 @@ import Data.Aeson
94 , Object, Array
105 , Object, Array
95 , withObject, withText, withArray, withScientific, withBool
106 , withObject, withText, withArray, withScientific, withBool
96 )
107 )
97−#if MIN_VERSION_aeson(1,0,0)
98−import Data.Aeson.Text (encodeToTextBuilder)
99−#else
100−import Data.Aeson.Encode (encodeToTextBuilder)
101−#endif
102−import Data.Aeson.Types (Pair, parseMaybe, parseEither, Parser)
108+import Data.Aeson.Types (parseMaybe, parseEither, Parser)
103import Data.ByteString (ByteString)
109import Data.ByteString (ByteString)
104import Data.Conduit ((.|), runConduitRes)
110import Data.Conduit ((.|), runConduitRes)
105import qualified Data.Conduit.List as CL
111import qualified Data.Conduit.List as CL
106−import qualified Data.HashMap.Strict as M
107−import qualified Data.HashSet as HashSet
108−import Data.Text.Encoding (encodeUtf8)
109−import qualified Data.Text as T
110−import qualified Data.Text.Encoding as TE
111−import qualified Data.Text.Lazy as TL
112−import Data.Text.Lazy.Builder (toLazyText)
113import qualified Data.Vector as V
112import qualified Data.Vector as V
114import System.IO.Unsafe (unsafePerformIO)
113import System.IO.Unsafe (unsafePerformIO)
115import Data.Text (Text)
114import Data.Text (Text)
@@ -118,13 +117,6 @@ import Data.Yaml.Internal
118import Text.Libyaml hiding (encode, decode, encodeFile, decodeFile, encodeWith, encodeFileWith)
117import Text.Libyaml hiding (encode, decode, encodeFile, decodeFile, encodeWith, encodeFileWith)
119import qualified Text.Libyaml as Y
118import qualified Text.Libyaml as Y
120
119
121−-- |
122−-- @since 0.10.2.0
123−data EncodeOptions = EncodeOptions
124− { encodeOptionsStringStyle :: Text -> ( Tag, Style )
125− , encodeOptionsFormat :: FormatOptions
126− }
127−
128-- | Set the string style in the encoded YAML. This is a function that decides
120-- | Set the string style in the encoded YAML. This is a function that decides
129-- for each string the type of YAML string to output.
121-- for each string the type of YAML string to output.
130--
122--
@@ -149,25 +141,18 @@ setStringStyle s opts = opts { encodeOptionsStringStyle = s }
149setFormat :: FormatOptions -> EncodeOptions -> EncodeOptions
141setFormat :: FormatOptions -> EncodeOptions -> EncodeOptions
150setFormat f opts = opts { encodeOptionsFormat = f }
142setFormat f opts = opts { encodeOptionsFormat = f }
151
143
152−-- | Determine whether a string must be quoted in YAML and can't appear as plain text.
144+-- |
153−-- Useful if you want to use 'setStringStyle'.
154−--
155-- @since 0.10.2.0
145-- @since 0.10.2.0
156−isSpecialString :: Text -> Bool
146+data EncodeOptions = EncodeOptions
157−isSpecialString s = s `HashSet.member` specialStrings || isNumeric s
147+ { encodeOptionsStringStyle :: Text -> ( Tag, Style )
148+ , encodeOptionsFormat :: FormatOptions
149+ }
158
150
159-- |
151-- |
160-- @since 0.10.2.0
152-- @since 0.10.2.0
161defaultEncodeOptions :: EncodeOptions
153defaultEncodeOptions :: EncodeOptions
162defaultEncodeOptions = EncodeOptions
154defaultEncodeOptions = EncodeOptions
163− { encodeOptionsStringStyle = \s ->
155+ { encodeOptionsStringStyle = defaultStringStyle
164− -- Empty strings need special handling to ensure they get quoted. This avoids:
165− -- https://github.com/snoyberg/yaml/issues/24
166− case () of
167− ()
168− | "\n" `T.isInfixOf` s -> ( NoTag, Literal )
169− | isSpecialString s -> ( NoTag, SingleQuoted )
170− | otherwise -> ( StrTag, PlainNoTag )
171 , encodeOptionsFormat = defaultFormatOptions
156 , encodeOptionsFormat = defaultFormatOptions
172 }
157 }
173
158
@@ -180,7 +165,7 @@ encode = encodeWith defaultEncodeOptions
180-- @since 0.10.2.0
165-- @since 0.10.2.0
181encodeWith :: ToJSON a => EncodeOptions -> a -> ByteString
166encodeWith :: ToJSON a => EncodeOptions -> a -> ByteString
182encodeWith opts obj = unsafePerformIO $ runConduitRes
167encodeWith opts obj = unsafePerformIO $ runConduitRes
183− $ CL.sourceList (objToEvents opts $ toJSON obj)
168+ $ CL.sourceList (objToStream (encodeOptionsStringStyle opts) $ toJSON obj)
184 .| Y.encodeWith (encodeOptionsFormat opts)
169 .| Y.encodeWith (encodeOptionsFormat opts)
185
170
186-- | Encode a value into its YAML representation and save to the given file.
171-- | Encode a value into its YAML representation and save to the given file.
@@ -192,46 +177,9 @@ encodeFile = encodeFileWith defaultEncodeOptions
192-- @since 0.10.2.0
177-- @since 0.10.2.0
193encodeFileWith :: ToJSON a => EncodeOptions -> FilePath -> a -> IO ()
178encodeFileWith :: ToJSON a => EncodeOptions -> FilePath -> a -> IO ()
194encodeFileWith opts fp obj = runConduitRes
179encodeFileWith opts fp obj = runConduitRes
195− $ CL.sourceList (objToEvents opts $ toJSON obj)
180+ $ CL.sourceList (objToStream (encodeOptionsStringStyle opts) $ toJSON obj)
196 .| Y.encodeFileWith (encodeOptionsFormat opts) fp
181 .| Y.encodeFileWith (encodeOptionsFormat opts) fp
197
182
198−objToEvents :: EncodeOptions -> Value -> [Y.Event]
199−objToEvents opts o = (:) EventStreamStart
200− . (:) EventDocumentStart
201− $ objToEvents' o
202− [ EventDocumentEnd
203− , EventStreamEnd
204− ]
205− where
206− objToEvents' :: Value -> [Y.Event] -> [Y.Event]
207− --objToEvents' (Scalar s) rest = scalarToEvent s : rest
208− objToEvents' (Array list) rest =
209− EventSequenceStart NoTag AnySequence Nothing
210− : foldr objToEvents' (EventSequenceEnd : rest) (V.toList list)
211− objToEvents' (Object pairs) rest =
212− EventMappingStart NoTag AnyMapping Nothing
213− : foldr pairToEvents (EventMappingEnd : rest) (M.toList pairs)
214−
215− objToEvents' (String "") rest = EventScalar "" NoTag SingleQuoted Nothing : rest
216−
217− objToEvents' (String s) rest = EventScalar (encodeUtf8 s) tag style Nothing : rest
218− where
219− ( tag, style ) = encodeOptionsStringStyle opts s
220− objToEvents' Null rest = EventScalar "null" NullTag PlainNoTag Nothing : rest
221− objToEvents' (Bool True) rest = EventScalar "true" BoolTag PlainNoTag Nothing : rest
222− objToEvents' (Bool False) rest = EventScalar "false" BoolTag PlainNoTag Nothing : rest
223− -- Use aeson's implementation which gets rid of annoying decimal points
224− objToEvents' n@Number{} rest = EventScalar (TE.encodeUtf8 $ TL.toStrict $ toLazyText $ encodeToTextBuilder n) IntTag PlainNoTag Nothing : rest
225−
226− pairToEvents :: Pair -> [Y.Event] -> [Y.Event]
227− pairToEvents (k, v) = objToEvents' (String k) . objToEvents' v
228−
229−{- FIXME
230−scalarToEvent :: YamlScalar -> Event
231−scalarToEvent (YamlScalar v t s) = EventScalar v t s Nothing
232−-}
233−
234−
235decode :: FromJSON a
183decode :: FromJSON a
236 => ByteString
184 => ByteString
237 -> Maybe a
185 -> Maybe a
@@ -255,6 +203,15 @@ decodeFileEither
255 -> IO (Either ParseException a)
203 -> IO (Either ParseException a)
256decodeFileEither = fmap (fmap snd) . decodeFileWithWarnings
204decodeFileEither = fmap (fmap snd) . decodeFileWithWarnings
257
205
206+-- | Like `decodeFileEither`, but decode multiple documents.
207+--
208+-- @since 0.11.5.0
209+decodeAllFileEither
210+ :: FromJSON a
211+ => FilePath
212+ -> IO (Either ParseException [a])
213+decodeAllFileEither = fmap (fmap snd) . decodeAllFileWithWarnings
214+
258-- | A version of `decodeFileEither` that returns warnings along with the parse
215-- | A version of `decodeFileEither` that returns warnings along with the parse
259-- result.
216-- result.
260--
217--
@@ -265,6 +222,15 @@ decodeFileWithWarnings
265 -> IO (Either ParseException ([Warning], a))
222 -> IO (Either ParseException ([Warning], a))
266decodeFileWithWarnings = decodeHelper_ . Y.decodeFile
223decodeFileWithWarnings = decodeHelper_ . Y.decodeFile
267
224
225+-- | Like `decodeFileWithWarnings`, but decode multiple documents.
226+--
227+-- @since 0.11.5.0
228+decodeAllFileWithWarnings
229+ :: FromJSON a
230+ => FilePath
231+ -> IO (Either ParseException ([Warning], [a]))
232+decodeAllFileWithWarnings = decodeAllHelper_ . Y.decodeFile
233+
268decodeEither :: FromJSON a => ByteString -> Either String a
234decodeEither :: FromJSON a => ByteString -> Either String a
269decodeEither bs = unsafePerformIO
235decodeEither bs = unsafePerformIO
270 $ either (Left . prettyPrintParseException) id
236 $ either (Left . prettyPrintParseException) id
@@ -280,21 +246,47 @@ decodeEither' = either Left (either (Left . AesonException) Right)
280 . fmap (fmap snd) . decodeHelper
246 . fmap (fmap snd) . decodeHelper
281 . Y.decode
247 . Y.decode
282
248
249+-- | Like 'decodeEither'', but decode multiple documents.
250+--
251+-- @since 0.11.5.0
252+decodeAllEither' :: FromJSON a => ByteString -> Either ParseException [a]
253+decodeAllEither' = either Left (either (Left . AesonException) Right)
254+ . unsafePerformIO
255+ . fmap (fmap snd) . decodeAllHelper
256+ . Y.decode
257+
283-- | A version of 'decodeEither'' lifted to MonadThrow
258-- | A version of 'decodeEither'' lifted to MonadThrow
284--
259--
285-- @since 0.8.31
260-- @since 0.8.31
286decodeThrow :: (MonadThrow m, FromJSON a) => ByteString -> m a
261decodeThrow :: (MonadThrow m, FromJSON a) => ByteString -> m a
287decodeThrow = either throwM return . decodeEither'
262decodeThrow = either throwM return . decodeEither'
288
263
264+-- | Like `decodeThrow`, but decode multiple documents.
265+--
266+-- @since 0.11.5.0
267+decodeAllThrow :: (MonadThrow m, FromJSON a) => ByteString -> m [a]
268+decodeAllThrow = either throwM return . decodeAllEither'
269+
289-- | A version of 'decodeFileEither' lifted to MonadIO
270-- | A version of 'decodeFileEither' lifted to MonadIO
290--
271--
291-- @since 0.8.31
272-- @since 0.8.31
292decodeFileThrow :: (MonadIO m, FromJSON a) => FilePath -> m a
273decodeFileThrow :: (MonadIO m, FromJSON a) => FilePath -> m a
293decodeFileThrow f = liftIO $ decodeFileEither f >>= either throwIO return
274decodeFileThrow f = liftIO $ decodeFileEither f >>= either throwIO return
294
275
276+-- | Like `decodeFileThrow`, but decode multiple documents.
277+--
278+-- @since 0.11.5.0
279+decodeAllFileThrow :: (MonadIO m, FromJSON a) => FilePath -> m [a]
280+decodeAllFileThrow f = liftIO $ decodeAllFileEither f >>= either throwIO return
281+
295-- | Construct a new 'Value' from a list of 'Value's.
282-- | Construct a new 'Value' from a list of 'Value's.
296array :: [Value] -> Value
283array :: [Value] -> Value
297array = Array . V.fromList
284array = Array . V.fromList
298
285
286+#if MIN_VERSION_base(4, 13, 0)
287+parseMonad :: MonadFail m => (a -> Parser b) -> a -> m b
288+#else
299parseMonad :: Monad m => (a -> Parser b) -> a -> m b
289parseMonad :: Monad m => (a -> Parser b) -> a -> m b
290+#endif
300parseMonad p = either fail return . parseEither p
291parseMonad p = either fail return . parseEither p
292+{-# DEPRECATED parseMonad "With the MonadFail split, this function is going to be removed in the future. Please migrate to parseEither." #-}
src/Data/Yaml/Aeson.hs → yaml/src/Data/Yaml/Aeson.hsrenamed

The content is the same.

src/Data/Yaml/Builder.hs → yaml/src/Data/Yaml/Builder.hsrenamed+71−39
@@ -9,6 +9,9 @@ module Data.Yaml.Builder
9 , mapping
9 , mapping
10 , namedMapping
10 , namedMapping
11 , maybeNamedMapping
11 , maybeNamedMapping
12+ , mappingComplex
13+ , namedMappingComplex
14+ , maybeNamedMappingComplex
12 , array
15 , array
13 , namedArray
16 , namedArray
14 , maybeNamedArray
17 , maybeNamedArray
@@ -37,7 +40,6 @@ module Data.Yaml.Builder
37
40
38import Prelude hiding (null)
41import Prelude hiding (null)
39
42
40−import Control.Arrow (second)
41#if MIN_VERSION_aeson(1,0,0)
43#if MIN_VERSION_aeson(1,0,0)
42import Data.Aeson.Text (encodeToTextBuilder)
44import Data.Aeson.Text (encodeToTextBuilder)
43#else
45#else
@@ -47,10 +49,9 @@ import Data.Aeson.Types (Value(..))
47import Data.ByteString (ByteString)
49import Data.ByteString (ByteString)
48import qualified Data.ByteString.Char8 as S8
50import qualified Data.ByteString.Char8 as S8
49import Data.Conduit
51import Data.Conduit
50−import qualified Data.HashSet as HashSet
51import Data.Scientific (Scientific)
52import Data.Scientific (Scientific)
52import Data.Text (Text, unpack)
53import Data.Text (Text, unpack)
53−import Data.Text.Encoding (encodeUtf8)
54+import qualified Data.Text as T
54import qualified Data.Text.Encoding as TE
55import qualified Data.Text.Encoding as TE
55import qualified Data.Text.Lazy as TL
56import qualified Data.Text.Lazy as TL
56import Data.Text.Lazy.Builder (toLazyText)
57import Data.Text.Lazy.Builder (toLazyText)
@@ -68,119 +69,148 @@ class ToYaml a where
68 toYaml :: a -> YamlBuilder
69 toYaml :: a -> YamlBuilder
69instance ToYaml YamlBuilder where
70instance ToYaml YamlBuilder where
70 toYaml = id
71 toYaml = id
71−instance ToYaml a => ToYaml [(Text, a)] where
72+instance (ToYaml a, ToYaml b) => ToYaml [(a, b)] where
72− toYaml = mapping . map (second toYaml)
73+ toYaml = mappingComplex . map (\(k, v) -> (toYaml k, toYaml v))
73instance ToYaml a => ToYaml [a] where
74instance ToYaml a => ToYaml [a] where
74 toYaml = array . map toYaml
75 toYaml = array . map toYaml
75instance ToYaml Text where
76instance ToYaml Text where
76 toYaml = string
77 toYaml = string
78+instance {-# OVERLAPPING #-} ToYaml String where
79+ toYaml = string . T.pack
77instance ToYaml Int where
80instance ToYaml Int where
78− toYaml i = YamlBuilder (EventScalar (S8.pack $ show i) IntTag PlainNoTag Nothing:)
81+ toYaml i = YamlBuilder (EventScalar (S8.pack $ show i) NoTag PlainNoTag Nothing:)
82+instance ToYaml Double where
83+ toYaml i = YamlBuilder (EventScalar (S8.pack $ show i) NoTag PlainNoTag Nothing:)
84+instance ToYaml Scientific where
85+ toYaml = scientific
86+instance ToYaml Bool where
87+ toYaml = bool
88+instance ToYaml a => ToYaml (Maybe a) where
89+ toYaml = maybe null toYaml
79
90
80-- |
91-- |
81−-- @since 0.11.0
92+-- @since 0.10.3.0
82maybeNamedMapping :: Maybe Text -> [(Text, YamlBuilder)] -> YamlBuilder
93maybeNamedMapping :: Maybe Text -> [(Text, YamlBuilder)] -> YamlBuilder
83−maybeNamedMapping anchor pairs = YamlBuilder $ \rest ->
94+maybeNamedMapping anchor pairs = maybeNamedMappingComplex anchor complexPairs
84− EventMappingStart NoTag AnyMapping (unpack <$> anchor) : foldr addPair (EventMappingEnd : rest) pairs
85 where
95 where
86− addPair (key, YamlBuilder value) after
96+ complexPairs = map (\(k, v) -> (string k, v)) pairs
87− = EventScalar (encodeUtf8 key) StrTag PlainNoTag Nothing
88− : value after
89
97
98+-- |
99+-- @since 0.8.7
90mapping :: [(Text, YamlBuilder)] -> YamlBuilder
100mapping :: [(Text, YamlBuilder)] -> YamlBuilder
91mapping = maybeNamedMapping Nothing
101mapping = maybeNamedMapping Nothing
92
102
93-- |
103-- |
94−-- @since 0.11.0
104+-- @since 0.10.3.0
95namedMapping :: Text -> [(Text, YamlBuilder)] -> YamlBuilder
105namedMapping :: Text -> [(Text, YamlBuilder)] -> YamlBuilder
96namedMapping name = maybeNamedMapping $ Just name
106namedMapping name = maybeNamedMapping $ Just name
97
107
98-- |
108-- |
99−-- @since 0.11.0
109+-- @since 0.11.2.0
110+maybeNamedMappingComplex :: Maybe Text -> [(YamlBuilder, YamlBuilder)] -> YamlBuilder
111+maybeNamedMappingComplex anchor pairs = YamlBuilder $ \rest ->
112+ EventMappingStart NoTag AnyMapping (unpack <$> anchor) : foldr addPair (EventMappingEnd : rest) pairs
113+ where
114+ addPair (YamlBuilder key, YamlBuilder value) after = key $ value after
115+
116+-- |
117+-- @since 0.11.2.0
118+mappingComplex :: [(YamlBuilder, YamlBuilder)] -> YamlBuilder
119+mappingComplex = maybeNamedMappingComplex Nothing
120+
121+-- |
122+-- @since 0.11.2.0
123+namedMappingComplex :: Text -> [(YamlBuilder, YamlBuilder)] -> YamlBuilder
124+namedMappingComplex name = maybeNamedMappingComplex $ Just name
125+
126+-- |
127+-- @since 0.10.3.0
100maybeNamedArray :: Maybe Text -> [YamlBuilder] -> YamlBuilder
128maybeNamedArray :: Maybe Text -> [YamlBuilder] -> YamlBuilder
101maybeNamedArray anchor bs =
129maybeNamedArray anchor bs =
102 YamlBuilder $ (EventSequenceStart NoTag AnySequence (unpack <$> anchor):) . flip (foldr go) bs . (EventSequenceEnd:)
130 YamlBuilder $ (EventSequenceStart NoTag AnySequence (unpack <$> anchor):) . flip (foldr go) bs . (EventSequenceEnd:)
103 where
131 where
104 go (YamlBuilder b) = b
132 go (YamlBuilder b) = b
105
133
134+-- |
135+-- @since 0.8.7
106array :: [YamlBuilder] -> YamlBuilder
136array :: [YamlBuilder] -> YamlBuilder
107array = maybeNamedArray Nothing
137array = maybeNamedArray Nothing
108
138
109-- |
139-- |
110−-- @since 0.11.0
140+-- @since 0.10.3.0
111namedArray :: Text -> [YamlBuilder] -> YamlBuilder
141namedArray :: Text -> [YamlBuilder] -> YamlBuilder
112namedArray name = maybeNamedArray $ Just name
142namedArray name = maybeNamedArray $ Just name
113
143
114-- |
144-- |
115−-- @since 0.11.0
145+-- @since 0.10.3.0
116maybeNamedString :: Maybe Text -> Text -> YamlBuilder
146maybeNamedString :: Maybe Text -> Text -> YamlBuilder
117−-- Empty strings need special handling to ensure they get quoted. This avoids:
118−-- https://github.com/snoyberg/yaml/issues/24
119−maybeNamedString anchor "" = YamlBuilder (EventScalar "" NoTag SingleQuoted (unpack <$> anchor) :)
147+maybeNamedString anchor s = YamlBuilder (stringScalar defaultStringStyle anchor s :)
120−maybeNamedString anchor s =
121− YamlBuilder (event :)
122− where
123− event
124− -- Make sure that special strings are encoded as strings properly.
125− -- See: https://github.com/snoyberg/yaml/issues/31
126− | s `HashSet.member` specialStrings || isNumeric s = EventScalar (encodeUtf8 s) NoTag SingleQuoted $ unpack <$> anchor
127− | otherwise = EventScalar (encodeUtf8 s) StrTag PlainNoTag $ unpack <$> anchor
128
148
149+-- |
150+-- @since 0.8.7
129string :: Text -> YamlBuilder
151string :: Text -> YamlBuilder
130string = maybeNamedString Nothing
152string = maybeNamedString Nothing
131
153
132-- |
154-- |
133−-- @since 0.11.0
155+-- @since 0.10.3.0
134namedString :: Text -> Text -> YamlBuilder
156namedString :: Text -> Text -> YamlBuilder
135namedString name = maybeNamedString $ Just name
157namedString name = maybeNamedString $ Just name
136
158
137-- Use aeson's implementation which gets rid of annoying decimal points
159-- Use aeson's implementation which gets rid of annoying decimal points
138-- |
160-- |
139−-- @since 0.11.0
161+-- @since 0.10.3.0
140maybeNamedScientific :: Maybe Text -> Scientific -> YamlBuilder
162maybeNamedScientific :: Maybe Text -> Scientific -> YamlBuilder
141−maybeNamedScientific anchor n = YamlBuilder (EventScalar (TE.encodeUtf8 $ TL.toStrict $ toLazyText $ encodeToTextBuilder (Number n)) IntTag PlainNoTag (unpack <$> anchor) :)
163+maybeNamedScientific anchor n = YamlBuilder (EventScalar (TE.encodeUtf8 $ TL.toStrict $ toLazyText $ encodeToTextBuilder (Number n)) NoTag PlainNoTag (unpack <$> anchor) :)
142
164
165+-- |
166+-- @since 0.8.13
143scientific :: Scientific -> YamlBuilder
167scientific :: Scientific -> YamlBuilder
144scientific = maybeNamedScientific Nothing
168scientific = maybeNamedScientific Nothing
145
169
146-- |
170-- |
147−-- @since 0.11.0
171+-- @since 0.10.3.0
148namedScientific :: Text -> Scientific -> YamlBuilder
172namedScientific :: Text -> Scientific -> YamlBuilder
149namedScientific name = maybeNamedScientific $ Just name
173namedScientific name = maybeNamedScientific $ Just name
150
174
175+-- |
176+-- @since 0.8.13
151{-# DEPRECATED number "Use scientific" #-}
177{-# DEPRECATED number "Use scientific" #-}
152number :: Scientific -> YamlBuilder
178number :: Scientific -> YamlBuilder
153number = scientific
179number = scientific
154
180
155-- |
181-- |
156−-- @since 0.11.0
182+-- @since 0.10.3.0
157maybeNamedBool :: Maybe Text -> Bool -> YamlBuilder
183maybeNamedBool :: Maybe Text -> Bool -> YamlBuilder
158−maybeNamedBool anchor True = YamlBuilder (EventScalar "true" BoolTag PlainNoTag (unpack <$> anchor) :)
184+maybeNamedBool anchor True = YamlBuilder (EventScalar "true" NoTag PlainNoTag (unpack <$> anchor) :)
159−maybeNamedBool anchor False = YamlBuilder (EventScalar "false" BoolTag PlainNoTag (unpack <$> anchor) :)
185+maybeNamedBool anchor False = YamlBuilder (EventScalar "false" NoTag PlainNoTag (unpack <$> anchor) :)
160
186
187+-- |
188+-- @since 0.8.13
161bool :: Bool -> YamlBuilder
189bool :: Bool -> YamlBuilder
162bool = maybeNamedBool Nothing
190bool = maybeNamedBool Nothing
163
191
164-- |
192-- |
165−-- @since 0.11.0
193+-- @since 0.10.3.0
166namedBool :: Text -> Bool -> YamlBuilder
194namedBool :: Text -> Bool -> YamlBuilder
167namedBool name = maybeNamedBool $ Just name
195namedBool name = maybeNamedBool $ Just name
168
196
169-- |
197-- |
170−-- @since 0.11.0
198+-- @since 0.10.3.0
171maybeNamedNull :: Maybe Text -> YamlBuilder
199maybeNamedNull :: Maybe Text -> YamlBuilder
172−maybeNamedNull anchor = YamlBuilder (EventScalar "null" NullTag PlainNoTag (unpack <$> anchor) :)
200+maybeNamedNull anchor = YamlBuilder (EventScalar "null" NoTag PlainNoTag (unpack <$> anchor) :)
173
201
202+-- |
203+-- @since 0.8.13
174null :: YamlBuilder
204null :: YamlBuilder
175null = maybeNamedNull Nothing
205null = maybeNamedNull Nothing
176
206
177-- |
207-- |
178−-- @since 0.11.0
208+-- @since 0.10.3.0
179namedNull :: Text -> YamlBuilder
209namedNull :: Text -> YamlBuilder
180namedNull name = maybeNamedNull $ Just name
210namedNull name = maybeNamedNull $ Just name
181
211
182-- |
212-- |
183−-- @since 0.11.0
213+-- @since 0.10.3.0
184alias :: Text -> YamlBuilder
214alias :: Text -> YamlBuilder
185alias anchor = YamlBuilder (EventAlias (unpack anchor) :)
215alias anchor = YamlBuilder (EventAlias (unpack anchor) :)
186
216
@@ -191,6 +221,8 @@ toEvents (YamlBuilder front) =
191toSource :: (Monad m, ToYaml a) => a -> ConduitM i Event m ()
221toSource :: (Monad m, ToYaml a) => a -> ConduitM i Event m ()
192toSource = mapM_ yield . toEvents . toYaml
222toSource = mapM_ yield . toEvents . toYaml
193
223
224+-- |
225+-- @since 0.8.7
194toByteString :: ToYaml a => a -> ByteString
226toByteString :: ToYaml a => a -> ByteString
195toByteString = toByteStringWith defaultFormatOptions
227toByteString = toByteStringWith defaultFormatOptions
196
228
src/Data/Yaml/Config.hs → yaml/src/Data/Yaml/Config.hsrenamed+34−15
@@ -5,7 +5,7 @@
5-- In particular, merging environment variables with yaml values
5-- In particular, merging environment variables with yaml values
6--
6--
7-- 'loadYamlSettings' is a high-level API for loading YAML and merging environment variables.
7-- 'loadYamlSettings' is a high-level API for loading YAML and merging environment variables.
8−-- A yaml value of @_env:ENV_VAR:default@ will lookup the environment variable @ENV_VAR@.
8+-- A yaml value of @_env:ENV_VAR:default@ or just @_env:ENV_VAR@ will lookup the environment variable @ENV_VAR@.
9--
9--
10-- On a historical note, this code was taken directly from the yesod web framework's configuration module.
10-- On a historical note, this code was taken directly from the yesod web framework's configuration module.
11module Data.Yaml.Config
11module Data.Yaml.Config
@@ -33,7 +33,13 @@ import Data.Monoid
33import Data.Semigroup
33import Data.Semigroup
34import Data.List.NonEmpty (nonEmpty)
34import Data.List.NonEmpty (nonEmpty)
35import Data.Aeson
35import Data.Aeson
36+#if MIN_VERSION_aeson(2,0,0)
37+import qualified Data.Aeson.Key as K
38+import qualified Data.Aeson.KeyMap as H
39+import Data.Aeson.KeyMap (KeyMap)
40+#else
36import qualified Data.HashMap.Strict as H
41import qualified Data.HashMap.Strict as H
42+#endif
37import Data.Text (Text, pack)
43import Data.Text (Text, pack)
38import System.Environment (getArgs, getEnvironment)
44import System.Environment (getArgs, getEnvironment)
39import Control.Arrow ((***))
45import Control.Arrow ((***))
@@ -45,6 +51,16 @@ import qualified Data.Yaml.Include as YI
45import Data.Maybe (fromMaybe)
51import Data.Maybe (fromMaybe)
46import qualified Data.Text as T
52import qualified Data.Text as T
47
53
54+#if MIN_VERSION_aeson(2,0,0)
55+fromText :: T.Text -> Key
56+fromText = K.fromText
57+#else
58+fromText :: T.Text -> T.Text
59+fromText = id
60+
61+type KeyMap a = H.HashMap T.Text a
62+#endif
63+
48newtype MergedValue = MergedValue { getMergedValue :: Value }
64newtype MergedValue = MergedValue { getMergedValue :: Value }
49
65
50instance Semigroup MergedValue where
66instance Semigroup MergedValue where
@@ -64,7 +80,7 @@ mergeValues x _ = x
64--
80--
65-- @since 0.8.16
81-- @since 0.8.16
66applyEnvValue :: Bool -- ^ require an environment variable to be present?
82applyEnvValue :: Bool -- ^ require an environment variable to be present?
67− -> H.HashMap Text Text -> Value -> Value
83+ -> KeyMap Text -> Value -> Value
68applyEnvValue requireEnv' env =
84applyEnvValue requireEnv' env =
69 goV
85 goV
70 where
86 where
@@ -74,7 +90,7 @@ applyEnvValue requireEnv' env =
74 t2 <- T.stripPrefix "_env:" t1
90 t2 <- T.stripPrefix "_env:" t1
75 let (name, t3) = T.break (== ':') t2
91 let (name, t3) = T.break (== ':') t2
76 mdef = fmap parseValue $ T.stripPrefix ":" t3
92 mdef = fmap parseValue $ T.stripPrefix ":" t3
77− Just $ case H.lookup name env of
93+ Just $ case H.lookup (fromText name) env of
78 Just val ->
94 Just val ->
79 -- If the default value parses as a String, we treat the
95 -- If the default value parses as a String, we treat the
80 -- environment variable as a raw value and do not parse it.
96 -- environment variable as a raw value and do not parse it.
@@ -101,8 +117,8 @@ applyEnvValue requireEnv' env =
101-- | Get the actual environment as a @HashMap@ from @Text@ to @Text@.
117-- | Get the actual environment as a @HashMap@ from @Text@ to @Text@.
102--
118--
103-- @since 0.8.16
119-- @since 0.8.16
104−getCurrentEnv :: IO (H.HashMap Text Text)
120+getCurrentEnv :: IO (KeyMap Text)
105−getCurrentEnv = fmap (H.fromList . map (pack *** pack)) getEnvironment
121+getCurrentEnv = fmap (H.fromList . map (fromText . pack *** pack)) getEnvironment
106
122
107-- | A convenience wrapper around 'applyEnvValue' and 'getCurrentEnv'
123-- | A convenience wrapper around 'applyEnvValue' and 'getCurrentEnv'
108--
124--
@@ -118,8 +134,8 @@ applyCurrentEnv requireEnv' orig = flip (applyEnvValue requireEnv') orig <$> get
118data EnvUsage = IgnoreEnv
134data EnvUsage = IgnoreEnv
119 | UseEnv
135 | UseEnv
120 | RequireEnv
136 | RequireEnv
121− | UseCustomEnv (H.HashMap Text Text)
137+ | UseCustomEnv (KeyMap Text)
122− | RequireCustomEnv (H.HashMap Text Text)
138+ | RequireCustomEnv (KeyMap Text)
123
139
124-- | Do not use any environment variables, instead relying on defaults values
140-- | Do not use any environment variables, instead relying on defaults values
125-- in the config file.
141-- in the config file.
@@ -146,14 +162,14 @@ requireEnv = RequireEnv
146-- @HashMap@ as the environment.
162-- @HashMap@ as the environment.
147--
163--
148-- @since 0.8.16
164-- @since 0.8.16
149−useCustomEnv :: H.HashMap Text Text -> EnvUsage
165+useCustomEnv :: KeyMap Text -> EnvUsage
150useCustomEnv = UseCustomEnv
166useCustomEnv = UseCustomEnv
151
167
152-- | Same as 'requireEnv', but instead of the actual environment, use the
168-- | Same as 'requireEnv', but instead of the actual environment, use the
153-- provided @HashMap@ as the environment.
169-- provided @HashMap@ as the environment.
154--
170--
155-- @since 0.8.16
171-- @since 0.8.16
156−requireCustomEnv :: H.HashMap Text Text -> EnvUsage
172+requireCustomEnv :: KeyMap Text -> EnvUsage
157requireCustomEnv = RequireCustomEnv
173requireCustomEnv = RequireCustomEnv
158
174
159-- | Load the settings from the following three sources:
175-- | Load the settings from the following three sources:
@@ -169,6 +185,11 @@ requireCustomEnv = RequireCustomEnv
169--
185--
170-- > loadYamlSettings ["config/foo.yaml"] [] useEnv
186-- > loadYamlSettings ["config/foo.yaml"] [] useEnv
171--
187--
188+-- Alternatively you can configure settings through the Yaml @Value@ directly in Haskell.
189+-- For example, to load up settings from only from environment variables, you can use:
190+--
191+-- > loadYamlSettings [] [object ["connectionString" .= ("_env:DATABASE_URL" :: String)]] requireEnv
192+--
172-- @since 0.8.16
193-- @since 0.8.16
173loadYamlSettings
194loadYamlSettings
174 :: FromJSON settings
195 :: FromJSON settings
@@ -180,9 +201,7 @@ loadYamlSettings runTimeFiles compileValues envUsage = do
180 runValues <- forM runTimeFiles $ \fp -> do
201 runValues <- forM runTimeFiles $ \fp -> do
181 eres <- YI.decodeFileEither fp
202 eres <- YI.decodeFileEither fp
182 case eres of
203 case eres of
183− Left e -> do
204+ Left e -> throwIO (Y.LoadSettingsException fp e)
184− putStrLn $ "loadYamlSettings: Could not parse file as YAML: " ++ fp
185− throwIO e
186 Right value -> return value
205 Right value -> return value
187
206
188 value' <-
207 value' <-
@@ -197,9 +216,9 @@ loadYamlSettings runTimeFiles compileValues envUsage = do
197 UseCustomEnv env -> return $ applyEnvValue False env value'
216 UseCustomEnv env -> return $ applyEnvValue False env value'
198 RequireCustomEnv env -> return $ applyEnvValue True env value'
217 RequireCustomEnv env -> return $ applyEnvValue True env value'
199
218
200− case fromJSON value of
219+ case Y.parseEither parseJSON value of
201− Error s -> error $ "Could not convert to expected type: " ++ s
220+ Left s -> error $ "Could not convert to expected type: " ++ s
202− Success settings -> return settings
221+ Right settings -> return settings
203
222
204-- | Same as @loadYamlSettings@, but get the list of runtime config files from
223-- | Same as @loadYamlSettings@, but get the list of runtime config files from
205-- the command line arguments.
224-- the command line arguments.
src/Data/Yaml/Include.hs → yaml/src/Data/Yaml/Include.hsrenamed

The content is the same.

src/Data/Yaml/Internal.hs → yaml/src/Data/Yaml/Internal.hsrenamed+212−51
@@ -9,11 +9,20 @@ module Data.Yaml.Internal
9 , prettyPrintParseException
9 , prettyPrintParseException
10 , Warning(..)
10 , Warning(..)
11 , parse
11 , parse
12+ , Parse
12 , decodeHelper
13 , decodeHelper
13 , decodeHelper_
14 , decodeHelper_
15+ , decodeAllHelper
16+ , decodeAllHelper_
17+ , textToScientific
18+ , stringScalar
19+ , StringStyle
20+ , defaultStringStyle
21+ , isSpecialString
14 , specialStrings
22 , specialStrings
15 , isNumeric
23 , isNumeric
16− , textToScientific
24+ , objToStream
25+ , objToEvents
17 ) where
26 ) where
18
27
19#if !MIN_VERSION_base(4,8,0)
28#if !MIN_VERSION_base(4,8,0)
@@ -25,43 +34,81 @@ import Control.Monad (when, unless)
25import Control.Monad.Trans.Resource (ResourceT, runResourceT)
34import Control.Monad.Trans.Resource (ResourceT, runResourceT)
26import Control.Monad.State.Strict
35import Control.Monad.State.Strict
27import Control.Monad.Reader
36import Control.Monad.Reader
37+#if MIN_VERSION_aeson(2,1,2)
38+import Data.Aeson hiding (AesonException)
39+#else
28import Data.Aeson
40import Data.Aeson
29−import Data.Aeson.Internal (JSONPath, JSONPathElement(..))
41+#endif
42+#if MIN_VERSION_aeson(2,0,0)
43+import qualified Data.Aeson.Key as K
44+import qualified Data.Aeson.KeyMap as M
45+import Data.Aeson.KeyMap (KeyMap)
46+#else
47+import qualified Data.HashMap.Strict as M
48+#endif
49+#if MIN_VERSION_aeson(2,2,0)
50+import Data.Aeson.Types hiding (AesonException, parse)
51+#else
30import Data.Aeson.Types hiding (parse)
52import Data.Aeson.Types hiding (parse)
53+import Data.Aeson.Internal (JSONPath, JSONPathElement(..), formatError)
54+#endif
31import qualified Data.Attoparsec.Text as Atto
55import qualified Data.Attoparsec.Text as Atto
32import Data.Bits (shiftL, (.|.))
56import Data.Bits (shiftL, (.|.))
33import Data.ByteString (ByteString)
57import Data.ByteString (ByteString)
58+import qualified Data.ByteString.Builder as BB
59+import qualified Data.ByteString.Lazy as BL
60+import Data.ByteString.Builder.Scientific (scientificBuilder)
34import Data.Char (toUpper, ord)
61import Data.Char (toUpper, ord)
35−import Data.List
62+import qualified Data.List as List
36import Data.Conduit ((.|), ConduitM, runConduit)
63import Data.Conduit ((.|), ConduitM, runConduit)
37import qualified Data.Conduit.List as CL
64import qualified Data.Conduit.List as CL
38−import qualified Data.HashMap.Strict as M
39import qualified Data.HashSet as HashSet
65import qualified Data.HashSet as HashSet
40import Data.Map (Map)
66import Data.Map (Map)
41import qualified Data.Map as Map
67import qualified Data.Map as Map
42import Data.Set (Set)
68import Data.Set (Set)
43import qualified Data.Set as Set
69import qualified Data.Set as Set
44−import Data.Scientific (Scientific)
70+import Data.Scientific (Scientific, base10Exponent, coefficient)
45−import Data.Text (Text, pack)
71+import Data.Text (Text)
46import qualified Data.Text as T
72import qualified Data.Text as T
47−import Data.Text.Encoding (decodeUtf8With)
73+import Data.Text.Encoding (decodeUtf8With, encodeUtf8)
48import Data.Text.Encoding.Error (lenientDecode)
74import Data.Text.Encoding.Error (lenientDecode)
49import Data.Typeable
75import Data.Typeable
50import qualified Data.Vector as V
76import qualified Data.Vector as V
77+import Data.Void (Void)
51
78
52import qualified Text.Libyaml as Y
79import qualified Text.Libyaml as Y
53import Text.Libyaml hiding (encode, decode, encodeFile, decodeFile)
80import Text.Libyaml hiding (encode, decode, encodeFile, decodeFile)
54
81
82+#if MIN_VERSION_aeson(2,0,0)
83+fromText :: T.Text -> K.Key
84+fromText = K.fromText
85+
86+toText :: K.Key -> T.Text
87+toText = K.toText
88+#else
89+fromText :: T.Text -> T.Text
90+fromText = id
91+
92+toText :: Key -> T.Text
93+toText = id
94+
95+type KeyMap a = M.HashMap Text a
96+type Key = Text
97+#endif
98+
55data ParseException = NonScalarKey
99data ParseException = NonScalarKey
56 | UnknownAlias { _anchorName :: Y.AnchorName }
100 | UnknownAlias { _anchorName :: Y.AnchorName }
57 | UnexpectedEvent { _received :: Maybe Event
101 | UnexpectedEvent { _received :: Maybe Event
58 , _expected :: Maybe Event
102 , _expected :: Maybe Event
59 }
103 }
60 | InvalidYaml (Maybe YamlException)
104 | InvalidYaml (Maybe YamlException)
105+ | MultipleDocuments
61 | AesonException String
106 | AesonException String
62 | OtherParseException SomeException
107 | OtherParseException SomeException
108+ | NonStringKey JSONPath
63 | NonStringKeyAlias Y.AnchorName Value
109 | NonStringKeyAlias Y.AnchorName Value
64 | CyclicIncludes
110 | CyclicIncludes
111+ | LoadSettingsException FilePath ParseException
65 deriving (Show, Typeable)
112 deriving (Show, Typeable)
66
113
67instance Exception ParseException where
114instance Exception ParseException where
@@ -105,14 +152,17 @@ prettyPrintParseException pe = case pe of
105 _ -> ",\n" ++ context ++ ":\n"
152 _ -> ",\n" ++ context ++ ":\n"
106 , problem
153 , problem
107 ]
154 ]
155+ MultipleDocuments -> "Multiple YAML documents encountered"
108 AesonException s -> "Aeson exception:\n" ++ s
156 AesonException s -> "Aeson exception:\n" ++ s
109 OtherParseException exc -> "Generic parse exception:\n" ++ show exc
157 OtherParseException exc -> "Generic parse exception:\n" ++ show exc
158+ NonStringKey path -> formatError path "Non-string keys are not supported"
110 NonStringKeyAlias anchor value -> unlines
159 NonStringKeyAlias anchor value -> unlines
111 [ "Non-string key alias:"
160 [ "Non-string key alias:"
112 , " Anchor name: " ++ anchor
161 , " Anchor name: " ++ anchor
113 , " Value: " ++ show value
162 , " Value: " ++ show value
114 ]
163 ]
115 CyclicIncludes -> "Cyclic includes"
164 CyclicIncludes -> "Cyclic includes"
165+ LoadSettingsException fp exc -> "Could not parse file as YAML: " ++ fp ++ "\n" ++ prettyPrintParseException exc
116
166
117defineAnchor :: Value -> String -> ReaderT JSONPath (ConduitM e o Parse) ()
167defineAnchor :: Value -> String -> ReaderT JSONPath (ConduitM e o Parse) ()
118defineAnchor value name = modify (modifyAnchors $ Map.insert name value)
168defineAnchor value name = modify (modifyAnchors $ Map.insert name value)
@@ -146,24 +196,34 @@ requireEvent e = do
146
196
147parse :: ReaderT JSONPath (ConduitM Event o Parse) Value
197parse :: ReaderT JSONPath (ConduitM Event o Parse) Value
148parse = do
198parse = do
199+ docs <- parseAll
200+ case docs of
201+ [] -> return Null
202+ [doc] -> return doc
203+ _ -> liftIO $ throwIO MultipleDocuments
204+
205+parseAll :: ReaderT JSONPath (ConduitM Event o Parse) [Value]
206+parseAll = do
149 streamStart <- lift CL.head
207 streamStart <- lift CL.head
150 case streamStart of
208 case streamStart of
151 Nothing ->
209 Nothing ->
152 -- empty string input
210 -- empty string input
153− return Null
211+ return []
154− Just EventStreamStart -> do
212+ Just EventStreamStart ->
155− documentStart <- lift CL.head
156− case documentStart of
157− Just EventStreamEnd ->
158− -- empty file input, comment only string/file input
213+ -- empty file input, comment only string/file input
159− return Null
214+ parseDocs
215+ _ -> missed streamStart
216+ where
217+ parseDocs = do
218+ documentStart <- lift CL.head
219+ case documentStart of
220+ Just EventStreamEnd -> return []
160− Just EventDocumentStart -> do
221+ Just EventDocumentStart -> do
161− res <- parseO
222+ res <- parseO
162− requireEvent EventDocumentEnd
223+ requireEvent EventDocumentEnd
163− requireEvent EventStreamEnd
224+ (res :) <$> parseDocs
164− return res
225+ _ -> missed documentStart
165− _ -> liftIO $ throwIO $ UnexpectedEvent documentStart Nothing
166− _ -> liftIO $ throwIO $ UnexpectedEvent streamStart Nothing
226+ missed event = liftIO $ throwIO $ UnexpectedEvent event Nothing
167
227
168parseScalar :: ByteString -> Anchor -> Style -> Tag
228parseScalar :: ByteString -> Anchor -> Style -> Tag
169 -> ReaderT JSONPath (ConduitM Event o Parse) Text
229 -> ReaderT JSONPath (ConduitM Event o Parse) Text
@@ -228,9 +288,9 @@ parseS !n a front = do
228 o <- local (Index n :) parseO
288 o <- local (Index n :) parseO
229 parseS (succ n) a $ front . (:) o
289 parseS (succ n) a $ front . (:) o
230
290
231−parseM :: Set Text
291+parseM :: Set Key
232 -> Y.Anchor
292 -> Y.Anchor
233− -> M.HashMap Text Value
293+ -> KeyMap Value
234 -> ReaderT JSONPath (ConduitM Event o Parse) Value
294 -> ReaderT JSONPath (ConduitM Event o Parse) Value
235parseM mergedKeys a front = do
295parseM mergedKeys a front = do
236 me <- lift CL.head
296 me <- lift CL.head
@@ -241,14 +301,16 @@ parseM mergedKeys a front = do
241 return res
301 return res
242 _ -> do
302 _ -> do
243 s <- case me of
303 s <- case me of
244− Just (EventScalar v tag style a') -> parseScalar v a' style tag
304+ Just (EventScalar v tag style a') -> fromText <$> parseScalar v a' style tag
245 Just (EventAlias an) -> do
305 Just (EventAlias an) -> do
246 m <- lookupAnchor an
306 m <- lookupAnchor an
247 case m of
307 case m of
248 Nothing -> liftIO $ throwIO $ UnknownAlias an
308 Nothing -> liftIO $ throwIO $ UnknownAlias an
249− Just (String t) -> return t
309+ Just (String t) -> return $ fromText t
250 Just v -> liftIO $ throwIO $ NonStringKeyAlias an v
310 Just v -> liftIO $ throwIO $ NonStringKeyAlias an v
251− _ -> liftIO $ throwIO $ UnexpectedEvent me Nothing
311+ _ -> do
312+ path <- ask
313+ liftIO $ throwIO $ NonStringKey path
252
314
253 (mergedKeys', al') <- local (Key s :) $ do
315 (mergedKeys', al') <- local (Key s :) $ do
254 o <- parseO
316 o <- parseO
@@ -257,52 +319,151 @@ parseM mergedKeys a front = do
257 path <- reverse <$> ask
319 path <- reverse <$> ask
258 addWarning (DuplicateKey path)
320 addWarning (DuplicateKey path)
259 return (Set.delete s mergedKeys, M.insert s o front)
321 return (Set.delete s mergedKeys, M.insert s o front)
260− if s == pack "<<"
322+ if s == "<<"
261 then case o of
323 then case o of
262 Object l -> return (merge l)
324 Object l -> return (merge l)
263− Array l -> return $ merge $ foldl' mergeObjects M.empty $ V.toList l
325+ Array l -> return $ merge $ List.foldl' mergeObjects M.empty $ V.toList l
264 _ -> al
326 _ -> al
265 else al
327 else al
266 parseM mergedKeys' a al'
328 parseM mergedKeys' a al'
267 where mergeObjects al (Object om) = M.union al om
329 where mergeObjects al (Object om) = M.union al om
268 mergeObjects al _ = al
330 mergeObjects al _ = al
269
331
270− merge xs = (Set.fromList (M.keys xs \\ M.keys front), M.union front xs)
332+ merge xs = (Set.fromList (M.keys xs List.\\ M.keys front), M.union front xs)
333+
334+parseSrc :: ReaderT JSONPath (ConduitM Event Void Parse) val
335+ -> ConduitM () Event Parse ()
336+ -> IO (val, ParseState)
337+parseSrc eventParser src = runResourceT $ runStateT
338+ (runConduit $ src .| runReaderT eventParser [])
339+ (ParseState Map.empty [])
340+
341+mkHelper :: ReaderT JSONPath (ConduitM Event Void Parse) val -- ^ parse libyaml events as Value or [Value]
342+ -> (SomeException -> IO (Either ParseException a)) -- ^ what to do with unhandled exceptions
343+ -> ((val, ParseState) -> Either ParseException a) -- ^ further transform and parse results
344+ -> ConduitM () Event Parse () -- ^ the libyaml event (string/file) source
345+ -> IO (Either ParseException a)
346+mkHelper eventParser onOtherExc extractResults src = catches
347+ (extractResults <$> parseSrc eventParser src)
348+ [ Handler $ \pe -> return $ Left (pe :: ParseException)
349+ , Handler $ \ye -> return $ Left $ InvalidYaml $ Just (ye :: YamlException)
350+ , Handler $ \sae -> throwIO (sae :: SomeAsyncException)
351+ , Handler onOtherExc
352+ ]
271
353
272decodeHelper :: FromJSON a
354decodeHelper :: FromJSON a
273 => ConduitM () Y.Event Parse ()
355 => ConduitM () Y.Event Parse ()
274 -> IO (Either ParseException ([Warning], Either String a))
356 -> IO (Either ParseException ([Warning], Either String a))
275−decodeHelper src = do
357+decodeHelper = mkHelper parse throwIO $ \(v, st) ->
276− -- This used to be tryAny, but the fact is that catching async
358+ Right (parseStateWarnings st, parseEither parseJSON v)
277− -- exceptions is fine here. We'll rethrow them immediately in the
359+
278− -- otherwise clause.
360+decodeAllHelper :: FromJSON a
279− x <- try $ runResourceT $ runStateT (runConduit $ src .| runReaderT parse []) (ParseState Map.empty [])
361+ => ConduitM () Event Parse ()
280− case x of
362+ -> IO (Either ParseException ([Warning], Either String [a]))
281− Left e
363+decodeAllHelper = mkHelper parseAll throwIO $ \(vs, st) ->
282− | Just pe <- fromException e -> return $ Left pe
364+ Right (parseStateWarnings st, mapM (parseEither parseJSON) vs)
283− | Just ye <- fromException e -> return $ Left $ InvalidYaml $ Just (ye :: YamlException)
365+
284− | otherwise -> throwIO e
366+catchLeft :: SomeException -> IO (Either ParseException a)
285− Right (y, st) -> return $ Right (parseStateWarnings st, parseEither parseJSON y)
367+catchLeft = return . Left . OtherParseException
286
368
287decodeHelper_ :: FromJSON a
369decodeHelper_ :: FromJSON a
288 => ConduitM () Event Parse ()
370 => ConduitM () Event Parse ()
289 -> IO (Either ParseException ([Warning], a))
371 -> IO (Either ParseException ([Warning], a))
290−decodeHelper_ src = do
372+decodeHelper_ = mkHelper parse catchLeft $ \(v, st) ->
291− x <- try $ runResourceT $ runStateT (runConduit $ src .| runReaderT parse []) (ParseState Map.empty [])
373+ case parseEither parseJSON v of
292− return $ case x of
374+ Left e -> Left $ AesonException e
293− Left e
375+ Right x -> Right (parseStateWarnings st, x)
294− | Just pe <- fromException e -> Left pe
376+
295− | Just ye <- fromException e -> Left $ InvalidYaml $ Just (ye :: YamlException)
377+decodeAllHelper_ :: FromJSON a
296− | otherwise -> Left $ OtherParseException e
378+ => ConduitM () Event Parse ()
297− Right (y, st) -> either
379+ -> IO (Either ParseException ([Warning], [a]))
298− (Left . AesonException)
380+decodeAllHelper_ = mkHelper parseAll catchLeft $ \(vs, st) ->
299− Right
381+ case mapM (parseEither parseJSON) vs of
300− ((,) (parseStateWarnings st) <$> parseEither parseJSON y)
382+ Left e -> Left $ AesonException e
383+ Right xs -> Right (parseStateWarnings st, xs)
384+
385+type StringStyle = Text -> ( Tag, Style )
386+
387+-- | Encodes a string with the supplied style. This function handles the empty
388+-- string case properly to avoid https://github.com/snoyberg/yaml/issues/24
389+--
390+-- @since 0.11.2.0
391+stringScalar :: StringStyle -> Maybe Text -> Text -> Event
392+stringScalar _ anchor "" = EventScalar "" NoTag SingleQuoted (T.unpack <$> anchor)
393+stringScalar stringStyle anchor s = EventScalar (encodeUtf8 s) tag style (T.unpack <$> anchor)
394+ where
395+ ( tag, style ) = stringStyle s
396+
397+-- |
398+-- @since 0.11.2.0
399+defaultStringStyle :: StringStyle
400+defaultStringStyle = \s ->
401+ case () of
402+ ()
403+ | "\n" `T.isInfixOf` s -> ( NoTag, Literal )
404+ | isSpecialString s -> ( NoTag, SingleQuoted )
405+ | otherwise -> ( NoTag, PlainNoTag )
406+
407+-- | Determine whether a string must be quoted in YAML and can't appear as plain text.
408+-- Useful if you want to use 'setStringStyle'.
409+--
410+-- @since 0.10.2.0
411+isSpecialString :: Text -> Bool
412+isSpecialString s = s `HashSet.member` specialStrings || isNumeric s
301
413
302-- | Strings which must be escaped so as not to be treated as non-string scalars.
414-- | Strings which must be escaped so as not to be treated as non-string scalars.
415+--
416+-- @since 0.8.32
303specialStrings :: HashSet.HashSet Text
417specialStrings :: HashSet.HashSet Text
304specialStrings = HashSet.fromList $ T.words
418specialStrings = HashSet.fromList $ T.words
305 "y Y yes Yes YES n N no No NO true True TRUE false False FALSE on On ON off Off OFF null Null NULL ~ *"
419 "y Y yes Yes YES n N no No NO true True TRUE false False FALSE on On ON off Off OFF null Null NULL ~ *"
306
420
421+-- |
422+-- @since 0.8.32
307isNumeric :: Text -> Bool
423isNumeric :: Text -> Bool
308isNumeric = either (const False) (const True) . textToScientific
424isNumeric = either (const False) (const True) . textToScientific
425+
426+-- | Encode a value as a YAML document stream.
427+--
428+-- @since 0.11.2.0
429+objToStream :: ToJSON a => StringStyle -> a -> [Y.Event]
430+objToStream stringStyle o =
431+ (:) EventStreamStart
432+ . (:) EventDocumentStart
433+ $ objToEvents stringStyle o
434+ [ EventDocumentEnd
435+ , EventStreamEnd
436+ ]
437+
438+-- | Encode a value as a list of 'Event's.
439+--
440+-- @since 0.11.2.0
441+objToEvents :: ToJSON a => StringStyle -> a -> [Y.Event] -> [Y.Event]
442+objToEvents stringStyle = objToEvents' . toJSON
443+ where
444+ objToEvents' (Array list) rest =
445+ EventSequenceStart NoTag AnySequence Nothing
446+ : foldr objToEvents' (EventSequenceEnd : rest) (V.toList list)
447+
448+ objToEvents' (Object o) rest =
449+ EventMappingStart NoTag AnyMapping Nothing
450+ : foldr pairToEvents (EventMappingEnd : rest) (M.toList o)
451+ where
452+ pairToEvents :: Pair -> [Y.Event] -> [Y.Event]
453+ pairToEvents (k, v) = objToEvents' (String $ toText k) . objToEvents' v
454+
455+ objToEvents' (String s) rest = stringScalar stringStyle Nothing s : rest
456+
457+ objToEvents' Null rest = EventScalar "null" NullTag PlainNoTag Nothing : rest
458+
459+ objToEvents' (Bool True) rest = EventScalar "true" BoolTag PlainNoTag Nothing : rest
460+ objToEvents' (Bool False) rest = EventScalar "false" BoolTag PlainNoTag Nothing : rest
461+
462+ objToEvents' (Number s) rest =
463+ let builder
464+ -- Special case the 0 exponent to remove the trailing .0
465+ | base10Exponent s == 0 = BB.integerDec $ coefficient s
466+ | otherwise = scientificBuilder s
467+ lbs = BB.toLazyByteString builder
468+ bs = BL.toStrict lbs
469+ in EventScalar bs IntTag PlainNoTag Nothing : rest
src/Data/Yaml/Parser.hs → yaml/src/Data/Yaml/Parser.hsrenamed+3
@@ -52,6 +52,9 @@ instance Monad YamlParser where
52 case f am of
52 case f am of
53 Left t -> Left t
53 Left t -> Left t
54 Right x -> unYamlParser (g x) am
54 Right x -> unYamlParser (g x) am
55+#if MIN_VERSION_base(4,13,0)
56+instance MonadFail YamlParser where
57+#endif
55 fail = YamlParser . const . Left . pack
58 fail = YamlParser . const . Left . pack
56instance MonadPlus YamlParser where
59instance MonadPlus YamlParser where
57 mzero = fail "mzero"
60 mzero = fail "mzero"
src/Data/Yaml/Pretty.hs → yaml/src/Data/Yaml/Pretty.hsrenamed+20−3
@@ -10,6 +10,7 @@ module Data.Yaml.Pretty
10 , getConfDropNull
10 , getConfDropNull
11 , setConfDropNull
11 , setConfDropNull
12 , defConfig
12 , defConfig
13+ , pretty
13 ) where
14 ) where
14
15
15import Prelude hiding (null)
16import Prelude hiding (null)
@@ -17,10 +18,16 @@ import Prelude hiding (null)
17#if !MIN_VERSION_base(4,8,0)
18#if !MIN_VERSION_base(4,8,0)
18import Control.Applicative ((<$>))
19import Control.Applicative ((<$>))
19#endif
20#endif
21+import Data.Bifunctor (first)
22+#if MIN_VERSION_aeson(2,0,0)
23+import qualified Data.Aeson.Key as K
24+import qualified Data.Aeson.KeyMap as HM
25+#else
26+import qualified Data.HashMap.Strict as HM
27+#endif
20import Data.Aeson.Types
28import Data.Aeson.Types
21import Data.ByteString (ByteString)
29import Data.ByteString (ByteString)
22import Data.Function (on)
30import Data.Function (on)
23−import qualified Data.HashMap.Strict as HM
24import Data.List (sortBy)
31import Data.List (sortBy)
25#if !MIN_VERSION_base(4,8,0)
32#if !MIN_VERSION_base(4,8,0)
26import Data.Monoid
33import Data.Monoid
@@ -30,11 +37,21 @@ import qualified Data.Vector as V
30
37
31import Data.Yaml.Builder
38import Data.Yaml.Builder
32
39
40+#if MIN_VERSION_aeson(2,0,0)
41+toText :: Key -> Text
42+toText = K.toText
43+#else
44+toText :: Key -> Text
45+toText = id
46+
47+type Key = Text
48+#endif
49+
33-- |
50-- |
34-- @since 0.8.13
51-- @since 0.8.13
35data Config = Config
52data Config = Config
36 { confCompare :: Text -> Text -> Ordering -- ^ Function used to sort keys in objects
53 { confCompare :: Text -> Text -> Ordering -- ^ Function used to sort keys in objects
37− , confDropNull :: Bool
54+ , confDropNull :: Bool -- ^ Drop null values from objects
38 }
55 }
39
56
40-- | The default configuration: do not sort objects or drop keys
57-- | The default configuration: do not sort objects or drop keys
@@ -71,7 +88,7 @@ pretty cfg = go
71 select
88 select
72 | confDropNull cfg = HM.filter (/= Null)
89 | confDropNull cfg = HM.filter (/= Null)
73 | otherwise = id
90 | otherwise = id
74− in mapping (sort $ HM.toList $ HM.map go $ select o)
91+ in mapping (sort $ fmap (first toText) $ HM.toList $ HM.map go $ select o)
75 go (Array a) = array (go <$> V.toList a)
92 go (Array a) = array (go <$> V.toList a)
76 go Null = null
93 go Null = null
77 go (String s) = string s
94 go (String s) = string s
src/Data/Yaml/TH.hs → yaml/src/Data/Yaml/TH.hsrenamed

The content is the same.

test/Data/Yaml/IncludeSpec.hs → yaml/test/Data/Yaml/IncludeSpec.hsrenamed+5
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
1{-# LANGUAGE QuasiQuotes #-}
2{-# LANGUAGE QuasiQuotes #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE OverloadedStrings #-}
3module Data.Yaml.IncludeSpec (main, spec) where
4module Data.Yaml.IncludeSpec (main, spec) where
@@ -6,7 +7,11 @@ import Test.Hspec
6import Data.List (isPrefixOf)
7import Data.List (isPrefixOf)
7import qualified Data.ByteString.Lazy as LB
8import qualified Data.ByteString.Lazy as LB
8import Data.Aeson
9import Data.Aeson
10+#if MIN_VERSION_aeson(2,2,0)
11+import Data.Aeson.Types (JSONPathElement(..))
12+#else
9import Data.Aeson.Internal (JSONPathElement(..))
13import Data.Aeson.Internal (JSONPathElement(..))
14+#endif
10import Data.Yaml (ParseException(InvalidYaml))
15import Data.Yaml (ParseException(InvalidYaml))
11import Data.Yaml.Include
16import Data.Yaml.Include
12import Data.Yaml.Internal
17import Data.Yaml.Internal
test/Data/Yaml/THSpec.hs → yaml/test/Data/Yaml/THSpec.hsrenamed

The content is the same.

test/Data/YamlSpec.hs → yaml/test/Data/YamlSpec.hsrenamed+301−26
@@ -8,8 +8,10 @@
8module Data.YamlSpec (main, spec) where
8module Data.YamlSpec (main, spec) where
9
9
10import qualified Text.Libyaml as Y
10import qualified Text.Libyaml as Y
11+import qualified Data.ByteString as BS
11import qualified Data.ByteString.Char8 as B8
12import qualified Data.ByteString.Char8 as B8
12import Data.Int (Int64)
13import Data.Int (Int64)
14+import qualified Data.Scientific as S
13
15
14import Test.HUnit hiding (Test, path)
16import Test.HUnit hiding (Test, path)
15
17
@@ -19,18 +21,29 @@ import qualified Data.Conduit.List as CL
19import Control.Monad
21import Control.Monad
20import Control.Exception (try, SomeException)
22import Control.Exception (try, SomeException)
21import Test.Hspec
23import Test.Hspec
24+import Test.Hspec.QuickCheck
22import Data.Either.Compat
25import Data.Either.Compat
23import System.Directory (createDirectory, createDirectoryIfMissing)
26import System.Directory (createDirectory, createDirectoryIfMissing)
24import Test.Mockery.Directory
27import Test.Mockery.Directory
25
28
26import qualified Data.Yaml as D
29import qualified Data.Yaml as D
30+import qualified Data.Yaml.Builder as B
31+import qualified Data.Yaml.Internal as Internal
27import qualified Data.Yaml.Pretty as Pretty
32import qualified Data.Yaml.Pretty as Pretty
28import Data.Yaml (object, array, (.=))
33import Data.Yaml (object, array, (.=))
29import Data.Maybe
34import Data.Maybe
35+import qualified Data.HashMap.Strict as HM
36+#if MIN_VERSION_aeson(2,0,0)
37+import qualified Data.Aeson.KeyMap as M
38+import qualified Data.Aeson.Key as K
39+import Data.Aeson.KeyMap (KeyMap)
40+#else
30import qualified Data.HashMap.Strict as M
41import qualified Data.HashMap.Strict as M
42+#endif
31import qualified Data.Text as T
43import qualified Data.Text as T
32import Data.Aeson.TH
44import Data.Aeson.TH
33import Data.Scientific (Scientific)
45import Data.Scientific (Scientific)
46+import Data.String (fromString)
34import Data.Text (Text)
47import Data.Text (Text)
35import Data.Text.Encoding (decodeUtf8, encodeUtf8)
48import Data.Text.Encoding (decodeUtf8, encodeUtf8)
36import Data.Vector (Vector)
49import Data.Vector (Vector)
@@ -40,6 +53,23 @@ import qualified Data.HashMap.Strict as HM
40import System.IO (hClose)
53import System.IO (hClose)
41import System.IO.Temp (withSystemTempFile)
54import System.IO.Temp (withSystemTempFile)
42
55
56+#if MIN_VERSION_aeson(2,0,0)
57+fromText :: T.Text -> K.Key
58+fromText = K.fromText
59+
60+toText :: K.Key -> T.Text
61+toText = K.toText
62+#else
63+fromText :: T.Text -> T.Text
64+fromText = id
65+
66+toText :: Key -> T.Text
67+toText = id
68+
69+type KeyMap a = M.HashMap Text a
70+type Key = Text
71+#endif
72+
43data TestJSON = TestJSON
73data TestJSON = TestJSON
44 { string :: Text
74 { string :: Text
45 , number :: Int
75 , number :: Int
@@ -50,10 +80,44 @@ data TestJSON = TestJSON
50
80
51deriveJSON defaultOptions ''TestJSON
81deriveJSON defaultOptions ''TestJSON
52
82
83+testJSON :: TestJSON
84+testJSON = TestJSON
85+ { string = "str"
86+ , number = 2
87+ , anArray = V.fromList ["a", "b"]
88+ , hash = HM.fromList [("key1", "value1"), ("key2", "value2")]
89+ , extrastring = "1234-foo"
90+ }
91+
53shouldDecode :: (Show a, D.FromJSON a, Eq a) => B8.ByteString -> a -> IO ()
92shouldDecode :: (Show a, D.FromJSON a, Eq a) => B8.ByteString -> a -> IO ()
54shouldDecode bs expected = do
93shouldDecode bs expected = do
55− actual <- D.decodeThrow bs
94+ actual <- D.decodeThrow bs
56− actual `shouldBe` expected
95+ actual `shouldBe` expected
96+
97+shouldDecodeAll :: (Show a, D.FromJSON a, Eq a) => B8.ByteString -> [a] -> IO ()
98+shouldDecodeAll bs expected = do
99+ actual <- D.decodeAllThrow bs
100+ actual `shouldBe` expected
101+
102+shouldDecodeEvents :: B8.ByteString -> [Y.Event] -> IO ()
103+shouldDecodeEvents bs expected = do
104+ actual <- runConduitRes $ Y.decode bs .| CL.consume
105+ map anyStyle actual `shouldBe` map anyStyle expected
106+
107+anyStyle :: Y.Event -> Y.Event
108+anyStyle (Y.EventScalar bs tag _ anchor) = Y.EventScalar bs tag Y.Any anchor
109+anyStyle (Y.EventSequenceStart tag _ anchor) = Y.EventSequenceStart tag Y.AnySequence anchor
110+anyStyle (Y.EventMappingStart tag _ anchor) = Y.EventMappingStart tag Y.AnyMapping anchor
111+anyStyle event = event
112+
113+testEncodeWith :: Y.FormatOptions -> [Y.Event] -> IO BS.ByteString
114+testEncodeWith opts es = runConduitRes $ CL.sourceList (eventStream es) .| Y.encodeWith opts
115+
116+eventStream :: [Y.Event] -> [Y.Event]
117+eventStream events =
118+ [Y.EventStreamStart, Y.EventDocumentStart]
119+ ++ events
120+ ++ [Y.EventDocumentEnd, Y.EventStreamEnd]
57
121
58main :: IO ()
122main :: IO ()
59main = hspec spec
123main = hspec spec
@@ -76,6 +140,7 @@ spec = do
76 it "count scalars" caseCountScalars
140 it "count scalars" caseCountScalars
77 it "largest string" caseLargestString
141 it "largest string" caseLargestString
78 it "encode/decode" caseEncodeDecode
142 it "encode/decode" caseEncodeDecode
143+ it "encode/decode events" caseEncodeDecodeEvents
79 it "encode/decode file" caseEncodeDecodeFile
144 it "encode/decode file" caseEncodeDecodeFile
80 it "interleaved encode/decode" caseInterleave
145 it "interleaved encode/decode" caseInterleave
81 it "decode invalid document (without segfault)" caseDecodeInvalidDocument
146 it "decode invalid document (without segfault)" caseDecodeInvalidDocument
@@ -91,6 +156,9 @@ spec = do
91 it "encode/decode" caseEncodeDecodeDataPretty
156 it "encode/decode" caseEncodeDecodeDataPretty
92 it "encode/decode strings" caseEncodeDecodeStringsPretty
157 it "encode/decode strings" caseEncodeDecodeStringsPretty
93 it "processes datatypes" caseDataTypesPretty
158 it "processes datatypes" caseDataTypesPretty
159+ describe "Data.Yaml.Builder" $ do
160+ it "encode/decode" caseEncodeDecodeDataBuilder
161+ it "encode/decode complex mapping" caseEncodeDecodeComplexMappingBuilder
94 describe "Data.Yaml aliases" $ do
162 describe "Data.Yaml aliases" $ do
95 it "simple scalar alias" caseSimpleScalarAlias
163 it "simple scalar alias" caseSimpleScalarAlias
96 it "simple sequence alias" caseSimpleSequenceAlias
164 it "simple sequence alias" caseSimpleSequenceAlias
@@ -136,7 +204,7 @@ spec = do
136
204
137 describe "special keys" $ do
205 describe "special keys" $ do
138 let tester key = it (T.unpack key) $
206 let tester key = it (T.unpack key) $
139− let value = object [key .= True]
207+ let value = object [fromText key .= True]
140 in D.encode value `shouldDecode` value
208 in D.encode value `shouldDecode` value
141 mapM_ tester specialStrings
209 mapM_ tester specialStrings
142
210
@@ -149,18 +217,21 @@ spec = do
149 describe "decodeFileEither" $ do
217 describe "decodeFileEither" $ do
150 it "loads YAML through JSON into Haskell data" $ do
218 it "loads YAML through JSON into Haskell data" $ do
151 tj <- either (error . show) id `fmap` D.decodeFileEither "test/json.yaml"
219 tj <- either (error . show) id `fmap` D.decodeFileEither "test/json.yaml"
152− tj `shouldBe` TestJSON
220+ tj `shouldBe` testJSON
153− { string = "str"
154− , number = 2
155− , anArray = V.fromList ["a", "b"]
156− , hash = HM.fromList [("key1", "value1"), ("key2", "value2")]
157− , extrastring = "1234-foo"
158− }
159
221
160 context "when file does not exist" $ do
222 context "when file does not exist" $ do
161 it "returns Left" $ do
223 it "returns Left" $ do
162 (D.decodeFileEither "./does_not_exist.yaml" :: IO (Either D.ParseException D.Value)) >>= (`shouldSatisfy` isLeft)
224 (D.decodeFileEither "./does_not_exist.yaml" :: IO (Either D.ParseException D.Value)) >>= (`shouldSatisfy` isLeft)
163
225
226+ describe "multiple document support" $ do
227+ it "decodes zero-length input" $
228+ "" `shouldDecodeAll` ([] :: [D.Value])
229+ it "decodes comment-only input" $
230+ "# foo\n# bar" `shouldDecodeAll` ([] :: [D.Value])
231+ it "decodes a single document stream" $
232+ "foo: true" `shouldDecodeAll` [object ["foo" .= True]]
233+ it "decodes multiple documents" $
234+ "--- 1\n--- 2" `shouldDecodeAll` [D.Number 1, D.Number 2]
164
235
165 describe "round-tripping of special scalars" $ do
236 describe "round-tripping of special scalars" $ do
166 let special = words "y Y On ON false 12345 12345.0 12345a 12e3"
237 let special = words "y Y On ON false 12345 12345.0 12345a 12e3"
@@ -178,18 +249,9 @@ spec = do
178
249
179 it "truncates files" caseTruncatesFiles
250 it "truncates files" caseTruncatesFiles
180
251
181− it "quoting keys #137" $ do
252+ it "encode quotes special keys #137" $ caseSpecialKeys D.encode
182− let keys = T.words "true false NO YES 1.2 1e5 null"
253+
183− bs = D.encode $ M.fromList $ map (, ()) keys
254+ it "encodePretty quotes special keys #179" $ caseSpecialKeys (Pretty.encodePretty Pretty.defConfig)
184− text = decodeUtf8 bs
185− forM_ keys $ \key -> do
186− let quoted = T.concat ["'", key, "'"]
187− unless (quoted `T.isInfixOf` text) $ error $ concat
188− [ "Could not find quoted key: "
189− , T.unpack quoted
190− , "\n\n"
191− , T.unpack text
192− ] :: IO ()
193
255
194 describe "non-decimal numbers #135" $ do
256 describe "non-decimal numbers #135" $ do
195 let go str val = it str $ encodeUtf8 (T.pack str) `shouldDecode` val
257 let go str val = it str $ encodeUtf8 (T.pack str) `shouldDecode` val
@@ -205,6 +267,110 @@ spec = do
205 go "12.3015e+02" (1230.15 :: Scientific)
267 go "12.3015e+02" (1230.15 :: Scientific)
206 go "1230.15" (1230.15 :: Scientific)
268 go "1230.15" (1230.15 :: Scientific)
207
269
270+ describe "Text.Libyaml with default tag rendering" $ do
271+ let enc = testEncodeWith Y.defaultFormatOptions
272+ it "elides custom sequence tags" $
273+ enc taggedSequence `shouldReturn` "[]\n"
274+ it "elides custom mapping tags" $
275+ enc taggedMapping `shouldReturn` "{}\n"
276+ it "elides default sequence tags" $
277+ enc defaultTaggedSequence `shouldReturn` "[]\n"
278+ it "elides default mapping tags" $
279+ enc defaultTaggedMapping `shouldReturn` "{}\n"
280+ it "handles NoTag on sequences" $
281+ enc untaggedSequence `shouldReturn` "[]\n"
282+ it "handles NoTag on mappings" $
283+ enc untaggedMapping `shouldReturn` "{}\n"
284+ it "handles mixed tag usages but elides all mapping and sequence tags" $
285+ enc mixedTagSampleA `shouldReturn` "- {}\n"
286+ it "in combination of tags, anchors and styles, outputs only the scalar tags" $
287+ enc mixedTagSampleB `shouldReturn` "&a\n&b !<bar> foo: &c [&d !!null '']\n"
288+ it "outputs tags when double quoted" $
289+ enc [Y.EventScalar "foo" Y.StrTag Y.DoubleQuoted Nothing] `shouldReturn` "!!str \"foo\"\n"
290+ it "outputs tags when single quoted" $
291+ enc [Y.EventScalar "foo" Y.StrTag Y.SingleQuoted Nothing] `shouldReturn` "!!str 'foo'\n"
292+ it "outputs tags on literal text" $
293+ enc [Y.EventScalar "foo" Y.StrTag Y.Literal Nothing] `shouldReturn` "!!str |-\n foo\n"
294+ it "outputs tags on folded text" $
295+ enc [Y.EventScalar "foo" Y.StrTag Y.Folded Nothing] `shouldReturn` "!!str >-\n foo\n"
296+ describe "Text.Libyaml with all tags on" $ do
297+ let enc = testEncodeWith $ Y.setTagRendering Y.renderAllTags Y.defaultFormatOptions
298+ it "will output custom sequence tags" $
299+ enc taggedSequence `shouldReturn` "!foo []\n"
300+ it "will output custom mapping tags" $
301+ enc taggedMapping `shouldReturn` "!foo {}\n"
302+ it "will output default sequence tags" $
303+ enc defaultTaggedSequence `shouldReturn` "!!seq []\n"
304+ it "will output default mapping tags" $
305+ enc defaultTaggedMapping `shouldReturn` "!!map {}\n"
306+ it "handles NoTag on sequences" $
307+ enc untaggedSequence `shouldReturn` "[]\n"
308+ it "handles NoTag on mappings" $
309+ enc untaggedMapping `shouldReturn` "{}\n"
310+ it "handles mixed tag usages outputting all mapping and sequence tags" $
311+ enc mixedTagSampleA `shouldReturn` "- !foo {}\n"
312+ it "in combination of tags, anchors and styles, outputs all the tags" $
313+ enc mixedTagSampleB `shouldReturn` "&a\n&b !<bar> foo: &c !baz [&d !!null '']\n"
314+ it "outputs plain tags" $
315+ enc [Y.EventScalar "foo" Y.StrTag Y.Plain Nothing] `shouldReturn` "!!str foo\n"
316+ it "respects PlainNoTag tags" $
317+ enc [Y.EventScalar "foo" Y.StrTag Y.PlainNoTag Nothing] `shouldReturn` "foo\n"
318+ describe "Text.Libyaml with uri tags on" $ do
319+ let enc = testEncodeWith $ Y.setTagRendering Y.renderUriTags Y.defaultFormatOptions
320+ it "will output custom sequence tags" $
321+ enc taggedSequence `shouldReturn` "!foo []\n"
322+ it "will output custom mapping tags" $
323+ enc taggedMapping `shouldReturn` "!foo {}\n"
324+ it "will output default sequence tags" $
325+ enc defaultTaggedSequence `shouldReturn` "[]\n"
326+ it "will output default mapping tags" $
327+ enc defaultTaggedMapping `shouldReturn` "{}\n"
328+ it "handles NoTag on sequences" $
329+ enc untaggedSequence `shouldReturn` "[]\n"
330+ it "handles NoTag on mappings" $
331+ enc untaggedMapping `shouldReturn` "{}\n"
332+ it "handles mixed tag usages outputting all mapping and sequence tags" $
333+ enc mixedTagSampleA `shouldReturn` "- !foo {}\n"
334+ it "in combination of tags, anchors and styles, outputs all the tags" $
335+ enc mixedTagSampleB `shouldReturn` "&a\n&b !<bar> foo: &c !baz [&d '']\n"
336+ describe "Text.Libyaml with tags off" $ do
337+ let enc = testEncodeWith $ Y.setTagRendering Y.renderNoTags Y.defaultFormatOptions
338+ it "outputs plain tags" $
339+ enc [Y.EventScalar "foo" Y.StrTag Y.Plain Nothing] `shouldReturn` "foo\n"
340+ it "respects PlainNoTag tags" $
341+ enc [Y.EventScalar "foo" Y.StrTag Y.PlainNoTag Nothing] `shouldReturn` "foo\n"
342+ it "elides tags when double quoted" $
343+ enc [Y.EventScalar "foo" Y.StrTag Y.DoubleQuoted Nothing] `shouldReturn` "\"foo\"\n"
344+ it "elides tags when single quoted" $
345+ enc [Y.EventScalar "foo" Y.StrTag Y.SingleQuoted Nothing] `shouldReturn` "'foo'\n"
346+ it "elides tags on literal text" $
347+ enc [Y.EventScalar "foo" Y.StrTag Y.Literal Nothing] `shouldReturn` "|-\n foo\n"
348+ it "elides tags on folded text" $
349+ enc [Y.EventScalar "foo" Y.StrTag Y.Folded Nothing] `shouldReturn` ">-\n foo\n"
350+ describe "Text.Libyaml with only UriTags set to render " $ do
351+ let enc =
352+ testEncodeWith $
353+ Y.setTagRendering Y.renderUriTags $ Y.defaultFormatOptions
354+ it "outputs only UriTags" $
355+ enc
356+ [ Y.EventSequenceStart Y.NoTag Y.FlowSequence Nothing
357+ , Y.EventScalar "foo" Y.StrTag Y.DoubleQuoted Nothing
358+ , Y.EventScalar "99" Y.IntTag Y.Plain Nothing
359+ , Y.EventScalar "99.99" Y.FloatTag Y.Plain Nothing
360+ , Y.EventScalar "bar" Y.NoTag Y.Plain Nothing
361+ , Y.EventScalar "foo" (Y.UriTag "!foo") Y.DoubleQuoted Nothing
362+ , Y.EventScalar "foo" (Y.UriTag "!foo") Y.Plain Nothing
363+ , Y.EventSequenceEnd
364+ ] `shouldReturn`
365+ "[\"foo\", 99, 99.99, bar, !foo \"foo\", !foo foo]\n"
366+
367+ prop "Scientific values round-trip" $ \coeff expon -> do
368+ let val = D.Number $ S.scientific coeff expon
369+ let rendered = D.encode val
370+ case D.decodeEither' rendered of
371+ Left e -> error $ show (coeff, expon, e)
372+ Right val' -> val' `shouldBe` val
373+
208specialStrings :: [T.Text]
374specialStrings :: [T.Text]
209specialStrings =
375specialStrings =
210 [ "fo\"o"
376 [ "fo\"o"
@@ -365,6 +531,13 @@ caseEncodeDecode = do
365 yamlString = "foo: bar\nbaz:\n - bin1\n - bin2\n"
531 yamlString = "foo: bar\nbaz:\n - bin1\n - bin2\n"
366 yamlBS = B8.pack yamlString
532 yamlBS = B8.pack yamlString
367
533
534+caseEncodeDecodeEvents :: Assertion
535+caseEncodeDecodeEvents = do
536+ let events = Internal.objToEvents D.defaultStringStyle testJSON []
537+ result <- Internal.decodeHelper_ . CL.sourceList $ eventStream events
538+ let (_, value) = either (error . show) id result
539+ value @?= testJSON
540+
368caseEncodeDecodeFile :: Assertion
541caseEncodeDecodeFile :: Assertion
369caseEncodeDecodeFile = withFile "" $ \tmpPath -> do
542caseEncodeDecodeFile = withFile "" $ \tmpPath -> do
370 eList <- runConduitRes $ Y.decodeFile filePath .| CL.consume
543 eList <- runConduitRes $ Y.decodeFile filePath .| CL.consume
@@ -403,7 +576,7 @@ mkStrScalar :: String -> D.Value
403mkStrScalar = D.String . T.pack
576mkStrScalar = D.String . T.pack
404
577
405mappingKey :: D.Value-> String -> D.Value
578mappingKey :: D.Value-> String -> D.Value
406−mappingKey (D.Object m) k = (fromJust . M.lookup (T.pack k) $ m)
579+mappingKey (D.Object m) k = (fromJust . M.lookup (fromText $ T.pack k) $ m)
407mappingKey _ _ = error "expected Object"
580mappingKey _ _ = error "expected Object"
408
581
409sample :: D.Value
582sample :: D.Value
@@ -414,6 +587,24 @@ sample = array
414 , ("bar3", D.String "")
587 , ("bar3", D.String "")
415 ]
588 ]
416 , D.String ""
589 , D.String ""
590+ , D.Number 1
591+ , D.Number 0.1
592+ , D.Bool True
593+ , D.Null
594+ ]
595+
596+sampleBuilder :: B.YamlBuilder
597+sampleBuilder = B.array
598+ [ B.string "foo"
599+ , B.mapping
600+ [ ("bar1", B.string "bar2")
601+ , ("bar3", B.string "")
602+ ]
603+ , B.string ""
604+ , B.scientific 1
605+ , B.scientific 0.1
606+ , B.bool True
607+ , B.null
417 ]
608 ]
418
609
419caseEncodeDecodeData :: Assertion
610caseEncodeDecodeData :: Assertion
@@ -423,6 +614,28 @@ caseEncodeDecodeDataPretty :: Assertion
423caseEncodeDecodeDataPretty =
614caseEncodeDecodeDataPretty =
424 Pretty.encodePretty Pretty.defConfig sample `shouldDecode` sample
615 Pretty.encodePretty Pretty.defConfig sample `shouldDecode` sample
425
616
617+caseEncodeDecodeDataBuilder :: Assertion
618+caseEncodeDecodeDataBuilder = do
619+ let events = B.unYamlBuilder sampleBuilder []
620+ bs <- testEncodeWith Y.defaultFormatOptions events
621+ bs `shouldDecodeEvents` eventStream events
622+
623+caseEncodeDecodeComplexMappingBuilder :: Assertion
624+caseEncodeDecodeComplexMappingBuilder = do
625+ let events = B.unYamlBuilder builder []
626+ bs <- testEncodeWith Y.defaultFormatOptions events
627+ bs `shouldDecodeEvents` eventStream events
628+ where
629+ builder :: B.YamlBuilder
630+ builder = B.mappingComplex
631+ [ ( B.mapping
632+ [ ("foo", B.scientific 1)
633+ , ("bar", B.scientific 2)
634+ ]
635+ , B.bool True
636+ )
637+ ]
638+
426caseEncodeDecodeFileData :: Assertion
639caseEncodeDecodeFileData :: Assertion
427caseEncodeDecodeFileData = withFile "" $ \fp -> do
640caseEncodeDecodeFileData = withFile "" $ \fp -> do
428 D.encodeFile fp sample
641 D.encodeFile fp sample
@@ -470,7 +683,9 @@ caseSimpleSequenceAlias =
470caseSimpleMappingAlias :: Assertion
683caseSimpleMappingAlias :: Assertion
471caseSimpleMappingAlias =
684caseSimpleMappingAlias =
472 "map: &anch\n key1: foo\n key2: baz\nmap2: *anch" `shouldDecode`
685 "map: &anch\n key1: foo\n key2: baz\nmap2: *anch" `shouldDecode`
473− object [(T.pack "map", object [("key1", mkScalar "foo"), ("key2", (mkScalar "baz"))]), (T.pack "map2", object [("key1", (mkScalar "foo")), ("key2", mkScalar "baz")])]
686+ object [(packStr "map", object [("key1", mkScalar "foo"), ("key2", (mkScalar "baz"))]), (packStr "map2", object [("key1", (mkScalar "foo")), ("key2", mkScalar "baz")])]
687+ where
688+ packStr = fromText . T.pack
474
689
475caseMappingAliasBeforeAnchor :: Assertion
690caseMappingAliasBeforeAnchor :: Assertion
476caseMappingAliasBeforeAnchor =
691caseMappingAliasBeforeAnchor =
@@ -607,9 +822,9 @@ casePreservesScientificPrecision = do
607 -- However, it didn't work (and still doesn't work with aeson < 0.7)
822 -- However, it didn't work (and still doesn't work with aeson < 0.7)
608 -- for two reasons:
823 -- for two reasons:
609 --
824 --
610− -- * We use 'Data.Text.Read.double', which is not as accurate as it
825+ -- - We use 'Data.Text.Read.double', which is not as accurate as it
611 -- can be;
826 -- can be;
612− -- * Even if we used 'Data.Text.Read.rational' we would not get good
827+ -- - Even if we used 'Data.Text.Read.rational' we would not get good
613 -- results, because of <https://github.com/bos/text/issues/34>.
828 -- results, because of <https://github.com/bos/text/issues/34>.
614 "x: 9.78159610558926e-5" `shouldDecode` object
829 "x: 9.78159610558926e-5" `shouldDecode` object
615 [ "x" .= D.Number (read "9.78159610558926e-5") ]
830 [ "x" .= D.Number (read "9.78159610558926e-5") ]
@@ -622,3 +837,63 @@ caseTruncatesFiles = withSystemTempFile "truncate.yaml" $ \fp h -> do
622 D.encodeFile fp val
837 D.encodeFile fp val
623 res <- D.decodeFileEither fp
838 res <- D.decodeFileEither fp
624 either (Left . show) Right res `shouldBe` Right val
839 either (Left . show) Right res `shouldBe` Right val
840+
841+caseSpecialKeys :: (KeyMap () -> B8.ByteString) -> Assertion
842+caseSpecialKeys encoder = do
843+ let keys = T.words "true false NO YES 1.2 1e5 null"
844+ bs = encoder $ M.fromList $ map (, ()) $ fmap fromText keys
845+ text = decodeUtf8 bs
846+ forM_ keys $ \key -> do
847+ let quoted = T.concat ["'", key, "'"]
848+ unless (quoted `T.isInfixOf` text) $ error $ concat
849+ [ "Could not find quoted key: "
850+ , T.unpack quoted
851+ , "\n\n"
852+ , T.unpack text
853+ ] :: IO ()
854+
855+taggedSequence :: [Y.Event]
856+taggedSequence =
857+ [ Y.EventSequenceStart (Y.UriTag "!foo") Y.FlowSequence Nothing
858+ , Y.EventSequenceEnd
859+ ]
860+
861+taggedMapping :: [Y.Event]
862+taggedMapping =
863+ [ Y.EventMappingStart (Y.UriTag "!foo") Y.FlowMapping Nothing
864+ , Y.EventMappingEnd
865+ ]
866+
867+defaultTaggedSequence :: [Y.Event]
868+defaultTaggedSequence =
869+ [Y.EventSequenceStart Y.SeqTag Y.FlowSequence Nothing, Y.EventSequenceEnd]
870+
871+defaultTaggedMapping :: [Y.Event]
872+defaultTaggedMapping =
873+ [Y.EventMappingStart Y.MapTag Y.FlowMapping Nothing, Y.EventMappingEnd]
874+
875+untaggedSequence :: [Y.Event]
876+untaggedSequence =
877+ [Y.EventSequenceStart Y.NoTag Y.FlowSequence Nothing, Y.EventSequenceEnd]
878+
879+untaggedMapping :: [Y.Event]
880+untaggedMapping =
881+ [Y.EventMappingStart Y.NoTag Y.FlowMapping Nothing, Y.EventMappingEnd]
882+
883+mixedTagSampleA :: [Y.Event]
884+mixedTagSampleA =
885+ [ Y.EventSequenceStart Y.NoTag Y.BlockSequence Nothing
886+ , Y.EventMappingStart (Y.UriTag "!foo") Y.FlowMapping Nothing
887+ , Y.EventMappingEnd
888+ , Y.EventSequenceEnd
889+ ]
890+
891+mixedTagSampleB :: [Y.Event]
892+mixedTagSampleB =
893+ [ Y.EventMappingStart Y.NoTag Y.BlockMapping (Just "a")
894+ , Y.EventScalar "foo" (Y.UriTag "bar") Y.Plain (Just "b")
895+ , Y.EventSequenceStart (Y.UriTag "!baz") Y.FlowSequence (Just "c")
896+ , Y.EventScalar "" Y.NullTag Y.Plain (Just "d")
897+ , Y.EventSequenceEnd
898+ , Y.EventMappingEnd
899+ ]
test/Spec.hs → yaml/test/Spec.hsrenamed

The content is the same.

test/json.yaml → yaml/test/json.yamlrenamed

The content is the same.

test/largest-string.yaml → yaml/test/largest-string.yamlrenamed

The content is the same.

test/resources/accent/foo.yaml → yaml/test/resources/accent/foo.yamlrenamed

The content is the same.

test/resources/bar.yaml → yaml/test/resources/bar.yamlrenamed

The content is the same.

test/resources/baz.yaml → yaml/test/resources/baz.yamlrenamed

The content is the same.

test/resources/empty.yaml → yaml/test/resources/empty.yamlrenamed

The content is the same.

test/resources/empty2.yaml → yaml/test/resources/empty2.yamlrenamed

The content is the same.

test/resources/foo.yaml → yaml/test/resources/foo.yamlrenamed

The content is the same.

test/resources/loop/bar.yaml → yaml/test/resources/loop/bar.yamlrenamed

The content is the same.

test/resources/loop/foo.yaml → yaml/test/resources/loop/foo.yamlrenamed

The content is the same.

yaml/yaml.cabalnew file+228
@@ -0,0 +1,228 @@
1+cabal-version: 1.12
2+
3+-- This file has been generated from package.yaml by hpack version 0.35.1.
4+--
5+-- see: https://github.com/sol/hpack
6+
7+name: yaml
8+version: 0.11.11.2
9+synopsis: Support for parsing and rendering YAML documents.
10+description: README and API documentation are available at <https://www.stackage.org/package/yaml>
11+category: Data
12+stability: stable
13+homepage: https://github.com/snoyberg/yaml#readme
14+bug-reports: https://github.com/snoyberg/yaml/issues
15+author: Michael Snoyman <michael@snoyman.com>, Anton Ageev <antage@gmail.com>,Kirill Simonov
16+maintainer: Michael Snoyman <michael@snoyman.com>
17+license: BSD3
18+license-file: LICENSE
19+build-type: Simple
20+extra-source-files:
21+ test/largest-string.yaml
22+ test/json.yaml
23+ test/resources/foo.yaml
24+ test/resources/bar.yaml
25+ test/resources/baz.yaml
26+ test/resources/accent/foo.yaml
27+ test/resources/loop/foo.yaml
28+ test/resources/loop/bar.yaml
29+ test/resources/empty.yaml
30+ test/resources/empty2.yaml
31+ README.md
32+ ChangeLog.md
33+
34+source-repository head
35+ type: git
36+ location: https://github.com/snoyberg/yaml
37+
38+flag no-examples
39+ description: don't build the examples
40+ manual: False
41+ default: True
42+
43+flag no-exe
44+ description: don't install the yaml2json or json2yaml executables
45+ manual: False
46+ default: True
47+
48+library
49+ exposed-modules:
50+ Data.Yaml
51+ Data.Yaml.Aeson
52+ Data.Yaml.Builder
53+ Data.Yaml.Config
54+ Data.Yaml.Include
55+ Data.Yaml.Internal
56+ Data.Yaml.Parser
57+ Data.Yaml.Pretty
58+ Data.Yaml.TH
59+ other-modules:
60+ Paths_yaml
61+ hs-source-dirs:
62+ src
63+ other-extensions:
64+ LambdaCase
65+ ghc-options: -Wall -Wcompat
66+ build-depends:
67+ aeson >=0.11
68+ , attoparsec >=0.11.3.0
69+ , base >=4.9.1 && <5
70+ , bytestring >=0.9.1.4
71+ , conduit >=1.2.8 && <1.4
72+ , containers
73+ , directory
74+ , filepath
75+ , libyaml ==0.1.*
76+ , mtl
77+ , resourcet >=0.3 && <1.4
78+ , scientific >=0.3
79+ , template-haskell
80+ , text
81+ , transformers >=0.1
82+ , unordered-containers
83+ , vector
84+ default-language: Haskell2010
85+
86+executable examples
87+ main-is: Main.hs
88+ other-modules:
89+ Config
90+ Simple
91+ Paths_yaml
92+ hs-source-dirs:
93+ examples
94+ ghc-options: -Wall -Wcompat
95+ build-depends:
96+ aeson >=0.11
97+ , attoparsec >=0.11.3.0
98+ , base >=4.9.1 && <5
99+ , bytestring >=0.9.1.4
100+ , conduit >=1.2.8 && <1.4
101+ , containers
102+ , directory
103+ , filepath
104+ , libyaml ==0.1.*
105+ , mtl
106+ , resourcet >=0.3 && <1.4
107+ , scientific >=0.3
108+ , template-haskell
109+ , text
110+ , transformers >=0.1
111+ , unordered-containers
112+ , vector
113+ default-language: Haskell2010
114+ if flag(no-examples)
115+ buildable: False
116+ else
117+ build-depends:
118+ raw-strings-qq
119+ , yaml
120+
121+executable json2yaml
122+ main-is: json2yaml.hs
123+ other-modules:
124+ Common
125+ Paths_yaml
126+ hs-source-dirs:
127+ exe
128+ ghc-options: -Wall -Wcompat
129+ build-depends:
130+ aeson >=0.11
131+ , attoparsec >=0.11.3.0
132+ , base >=4.9.1 && <5
133+ , bytestring >=0.9.1.4
134+ , conduit >=1.2.8 && <1.4
135+ , containers
136+ , directory
137+ , filepath
138+ , libyaml ==0.1.*
139+ , mtl
140+ , optparse-applicative
141+ , resourcet >=0.3 && <1.4
142+ , scientific >=0.3
143+ , template-haskell
144+ , text
145+ , transformers >=0.1
146+ , unordered-containers
147+ , vector
148+ , yaml
149+ default-language: Haskell2010
150+ if flag(no-exe)
151+ buildable: False
152+
153+executable yaml2json
154+ main-is: yaml2json.hs
155+ other-modules:
156+ Common
157+ Paths_yaml
158+ hs-source-dirs:
159+ exe
160+ other-extensions:
161+ CPP
162+ LambdaCase
163+ NamedFieldPuns
164+ ghc-options: -Wall -Wcompat
165+ build-depends:
166+ aeson >=0.11
167+ , attoparsec >=0.11.3.0
168+ , base >=4.9.1 && <5
169+ , bytestring >=0.9.1.4
170+ , conduit >=1.2.8 && <1.4
171+ , containers
172+ , directory
173+ , filepath
174+ , libyaml ==0.1.*
175+ , mtl
176+ , optparse-applicative
177+ , resourcet >=0.3 && <1.4
178+ , scientific >=0.3
179+ , template-haskell
180+ , text
181+ , transformers >=0.1
182+ , unordered-containers
183+ , vector
184+ , yaml
185+ default-language: Haskell2010
186+ if flag(no-exe)
187+ buildable: False
188+
189+test-suite spec
190+ type: exitcode-stdio-1.0
191+ main-is: Spec.hs
192+ other-modules:
193+ Data.Yaml.IncludeSpec
194+ Data.Yaml.THSpec
195+ Data.YamlSpec
196+ Paths_yaml
197+ hs-source-dirs:
198+ test
199+ ghc-options: -Wall -Wcompat -with-rtsopts=-K1K
200+ cpp-options: -DTEST
201+ build-tool-depends:
202+ hspec-discover:hspec-discover
203+ build-depends:
204+ HUnit
205+ , aeson >=0.11
206+ , attoparsec >=0.11.3.0
207+ , base >=4.9.1 && <5
208+ , base-compat
209+ , bytestring >=0.9.1.4
210+ , conduit >=1.2.8 && <1.4
211+ , containers
212+ , directory
213+ , filepath
214+ , hspec >=1.3
215+ , libyaml ==0.1.*
216+ , mockery
217+ , mtl
218+ , raw-strings-qq
219+ , resourcet >=0.3 && <1.4
220+ , scientific >=0.3
221+ , template-haskell
222+ , temporary
223+ , text
224+ , transformers >=0.1
225+ , unordered-containers
226+ , vector
227+ , yaml
228+ default-language: Haskell2010