on master help sign in
68 files changed+1674−13417
since splitsnapshots
unifiedsplit
.github/workflows/tests.yml+44 .gitignore+2−2 .gitmodules+1−1 .travis.yml−232 README.md+15−12 appveyor.yml−32 copy-libyaml.sh−10 exe/json2yaml.hs−22 exe/yaml2json.hs−31 libyaml/ChangeLog.md+27 libyaml/LICENSE+22−17 Makefile → libyaml/Makefile libyaml/README.md+3 libyaml/Setup.hs+2 libyaml/api.c−1402 c/helper.c → libyaml/c/helper.c libyaml/dumper.c−394 libyaml/emitter.c−2324 c/helper.h → libyaml/include/helper.h libyaml/libyaml.cabal+68 libyaml/loader.c−444 libyaml/package.yaml+53 libyaml/parser.c−1370 libyaml/reader.c−469 libyaml/scanner.c−3578 src/Text/Libyaml.hs → libyaml/src/Text/Libyaml.hs+104−19 libyaml/writer.c−141 libyaml/yaml.h−1973 libyaml/yaml_private.h−690 stack.yaml+8−1 vendor/libyaml−1 ChangeLog.md → yaml/ChangeLog.md+84 LICENSE → yaml/LICENSE yaml/README.md+26 Setup.lhs → yaml/Setup.lhs builder-test.hs → yaml/builder-test.hs examples/Config.hs → yaml/examples/Config.hs examples/Main.hs → yaml/examples/Main.hs examples/Simple.hs → yaml/examples/Simple.hs yaml/exe/Common.hs+68 yaml/exe/json2yaml.hs+106 yaml/exe/yaml2json.hs+87 package.yaml → yaml/package.yaml+16−46 parser-test.hs → yaml/parser-test.hs src/Data/Yaml.hs → yaml/src/Data/Yaml.hs+64−72 src/Data/Yaml/Aeson.hs → yaml/src/Data/Yaml/Aeson.hs src/Data/Yaml/Builder.hs → yaml/src/Data/Yaml/Builder.hs+71−39 src/Data/Yaml/Config.hs → yaml/src/Data/Yaml/Config.hs+34−15 src/Data/Yaml/Include.hs → yaml/src/Data/Yaml/Include.hs src/Data/Yaml/Internal.hs → yaml/src/Data/Yaml/Internal.hs+212−51 src/Data/Yaml/Parser.hs → yaml/src/Data/Yaml/Parser.hs+3 src/Data/Yaml/Pretty.hs → yaml/src/Data/Yaml/Pretty.hs+20−3 src/Data/Yaml/TH.hs → yaml/src/Data/Yaml/TH.hs test/Data/Yaml/IncludeSpec.hs → yaml/test/Data/Yaml/IncludeSpec.hs+5 test/Data/Yaml/THSpec.hs → yaml/test/Data/Yaml/THSpec.hs test/Data/YamlSpec.hs → yaml/test/Data/YamlSpec.hs+301−26 test/Spec.hs → yaml/test/Spec.hs test/json.yaml → yaml/test/json.yaml test/largest-string.yaml → yaml/test/largest-string.yaml test/resources/accent/foo.yaml → yaml/test/resources/accent/foo.yaml test/resources/bar.yaml → yaml/test/resources/bar.yaml test/resources/baz.yaml → yaml/test/resources/baz.yaml test/resources/empty.yaml → yaml/test/resources/empty.yaml test/resources/empty2.yaml → yaml/test/resources/empty2.yaml test/resources/foo.yaml → yaml/test/resources/foo.yaml test/resources/loop/bar.yaml → yaml/test/resources/loop/bar.yaml test/resources/loop/foo.yaml → yaml/test/resources/loop/foo.yaml yaml/yaml.cabal+228
.github/workflows/tests.ymlnew file+44
@@ -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/
55cabal.sandbox.config
66.stack-work/
77*~
8−yaml.cabal
9−/tarballs/
8+tarballs/
109.dir-locals.el
1110*#
11+stack.yaml.lock
.gitmodules+1−1
@@ -1,3 +1,3 @@
11[submodule "vendor/libyaml"]
2− path = vendor/libyaml
2+ path = libyaml/vendor/libyaml
33 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
22
3−[![Build Status](https://travis-ci.org/snoyberg/yaml.svg?branch=master)](https://travis-ci.org/snoyberg/yaml)
4−[![Build status](https://ci.appveyor.com/api/projects/status/hqy2jketp8m502so/branch/master?svg=true)](https://ci.appveyor.com/project/snoyberg/yaml/branch/master)
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)
54
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.
77
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
99
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.
1113
12−### Examples
14+## `libyaml` Package
1315
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.
1519
16−### Additional modules
20+## License
1721
18−* `Data.Yaml.Include` supports adding `!include` directives to your YAML files.
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.
20−* `Data.Yaml.Aeson` is currently a re-export of `Data.Yaml` to explicitly choose to use the aeson-compatible API.
22+This project is licensed with the BSD 3-Clause license. Copies of the license can be found in both the `yaml` and
23+`libyaml` subdirectories
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
2−Copyright (c) 2006-2016 Kirill Simonov
1+The following license covers this documentation, and the source code, except
2+where otherwise indicated.
33
4−Permission is hereby granted, free of charge, to any person obtaining a copy of
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:
4+Copyright 2008, Michael Snoyman. All rights reserved.
105
11−The above copyright notice and this permission notice shall be included in all
12−copies or substantial portions of the Software.
6+Redistribution and use in source and binary forms, with or without
7+modification, are permitted provided that the following conditions are met:
138
14−THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15−IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16−FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17−AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18−LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19−OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20−SOFTWARE.
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+
16+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR
17+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
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
23+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
24+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
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 @@
77{-# LANGUAGE RankNTypes #-}
88{-# LANGUAGE CPP #-}
99{-# LANGUAGE TypeFamilies #-}
10+{-# LANGUAGE ScopedTypeVariables #-}
1011
1112-- | Low-level, streaming YAML interface. For a higher-level interface, see
1213-- "Data.Yaml".
@@ -32,6 +33,11 @@ module Text.Libyaml
3233 , FormatOptions
3334 , defaultFormatOptions
3435 , setWidth
36+ , setTagRendering
37+ , renderScalarTags
38+ , renderAllTags
39+ , renderNoTags
40+ , renderUriTags
3541 -- * Error handling
3642 , YamlException (..)
3743 , YamlMark (..)
@@ -64,6 +70,11 @@ import qualified Data.ByteString.Char8 as B8
6470import qualified Data.ByteString.Internal as B
6571import qualified Data.ByteString.Unsafe as BU
6672
73+#if WINDOWS && __GLASGOW_HASKELL__ >= 806
74+import System.Directory (removeFile)
75+import qualified Control.Exception
76+#endif
77+
6778data Event =
6879 EventStreamStart
6980 | EventStreamEnd
@@ -121,6 +132,11 @@ data Tag = StrTag
121132 | NoTag
122133 deriving (Show, Eq, Read, Data, Typeable)
123134
135+tagSuppressed :: Tag -> Bool
136+tagSuppressed (NoTag) = True
137+tagSuppressed (UriTag "") = True
138+tagSuppressed _ = False
139+
124140type AnchorName = String
125141type Anchor = Maybe AnchorName
126142
@@ -209,10 +225,10 @@ foreign import ccall unsafe "fdopen"
209225 -> IO File
210226foreign import ccall unsafe "fclose"
211227 c_fclose :: File
212− -> IO ()
228+ -> IO CInt
213229
214230foreign import ccall unsafe "fclose_helper"
215− c_fclose_helper :: File -> IO ()
231+ c_fclose_helper :: File -> IO CInt
216232
217233foreign import ccall unsafe "yaml_parser_parse"
218234 c_yaml_parser_parse :: Parser -> EventRaw -> IO CInt
@@ -446,8 +462,8 @@ foreign import ccall unsafe "yaml_alias_event_initialize"
446462 -> Ptr CUChar
447463 -> IO CInt
448464
449−toEventRaw :: Event -> (EventRaw -> IO a) -> IO a
450−toEventRaw e f = allocaBytes eventSize $ \er -> do
465+toEventRaw :: FormatOptions -> Event -> (EventRaw -> IO a) -> IO a
466+toEventRaw opts e f = allocaBytes eventSize $ \er -> do
451467 ret <- case e of
452468 EventStreamStart ->
453469 c_yaml_stream_start_event_initialize
@@ -465,13 +481,13 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
465481 len' = fromIntegral len :: CInt
466482 let thetag' = tagToString thetag
467483 withCString thetag' $ \tag' -> do
468− let (pi, style) =
469− case style0 of
470− PlainNoTag -> (1, Plain)
471− x -> (0, x)
484+ let pi0 = tagsImplicit e
485+ (pi, style) =
486+ case style0 of
487+ PlainNoTag -> (1, Plain)
488+ x -> (pi0, x)
472489 style' = toEnum $ fromEnum style
473490 tagP = castPtr tag'
474− qi = if null thetag' then 1 else 0
475491 case anchor of
476492 Nothing ->
477493 c_yaml_scalar_event_initialize
@@ -481,7 +497,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
481497 value' -- value
482498 len' -- length
483499 pi -- plain_implicit
484− qi -- quoted_implicit
500+ pi -- quoted_implicit
485501 style' -- style
486502 Just anchor' ->
487503 withCString anchor' $ \anchorP' -> do
@@ -493,7 +509,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
493509 value' -- value
494510 len' -- length
495511 0 -- plain_implicit
496− qi -- quoted_implicit
512+ pi -- quoted_implicit
497513 style' -- style
498514 EventSequenceStart tag style Nothing ->
499515 withCString (tagToString tag) $ \tag' -> do
@@ -502,7 +518,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
502518 er
503519 nullPtr
504520 tagP
505− 1
521+ (tagsImplicit e)
506522 (toEnum $ fromEnum style)
507523 EventSequenceStart tag style (Just anchor) ->
508524 withCString (tagToString tag) $ \tag' -> do
@@ -513,7 +529,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
513529 er
514530 anchorP
515531 tagP
516− 1
532+ (tagsImplicit e)
517533 (toEnum $ fromEnum style)
518534 EventSequenceEnd ->
519535 c_yaml_sequence_end_event_initialize er
@@ -524,7 +540,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
524540 er
525541 nullPtr
526542 tagP
527− 1
543+ (tagsImplicit e)
528544 (toEnum $ fromEnum style)
529545 EventMappingStart tag style (Just anchor) ->
530546 withCString (tagToString tag) $ \tag' -> do
@@ -535,7 +551,7 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
535551 er
536552 anchorP
537553 tagP
538− 1
554+ (tagsImplicit e)
539555 (toEnum $ fromEnum style)
540556 EventMappingEnd ->
541557 c_yaml_mapping_end_event_initialize er
@@ -547,6 +563,11 @@ toEventRaw e f = allocaBytes eventSize $ \er -> do
547563 anchorP
548564 unless (ret == 1) $ throwIO $ ToEventRawException ret
549565 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
550571
551572newtype ToEventRawException = ToEventRawException CInt
552573 deriving (Show, Typeable)
@@ -638,7 +659,8 @@ decodeFileMarked file =
638659 c_yaml_parser_set_input_file ptr file'
639660 return (ptr, file')
640661 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
642664 c_yaml_parser_delete ptr
643665 free ptr
644666
@@ -663,11 +685,58 @@ parserParseOne' parser = allocaBytes eventSize $ \er -> do
663685 return $ Left $ YamlParseException problem context problemMark
664686 else Right <$> getEvent er
665687
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+
666734-- | Contains options relating to the formatting (indendation, width) of the YAML output.
667735--
668736-- @since 0.10.2.0
669737data FormatOptions = FormatOptions
670738 { formatOptionsWidth :: Maybe Int
739+ , formatOptionsRenderTags :: Event -> TagRender
671740 }
672741
673742-- |
@@ -675,6 +744,7 @@ data FormatOptions = FormatOptions
675744defaultFormatOptions :: FormatOptions
676745defaultFormatOptions = FormatOptions
677746 { 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
678748 }
679749
680750-- | 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
683753setWidth :: Maybe Int -> FormatOptions -> FormatOptions
684754setWidth w opts = opts { formatOptionsWidth = w }
685755
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+
686762encode :: MonadResource m => ConduitM Event o m ByteString
687763encode = encodeWith defaultFormatOptions
688764
@@ -700,7 +776,7 @@ encodeWith opts =
700776 close _ fbuf = withForeignPtr fbuf $ \b -> do
701777 ptr' <- c_get_buffer_buff b
702778 len <- c_get_buffer_used b
703− fptr <- newForeignPtr_ $ castPtr ptr'
779+ fptr <- newForeignPtr finalizerFree $ castPtr ptr'
704780 return $ B.fromForeignPtr fptr 0 $ fromIntegral len
705781
706782
@@ -716,9 +792,18 @@ encodeFileWith :: MonadResource m
716792 -> FilePath
717793 -> ConduitM Event o m ()
718794encodeFileWith 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)
720796 where
797+ cleanup file = do
798+ res <- c_fclose file
799+ when (res /= 0) $ throwIO $ YamlException $ "could not close file: " ++ filePath
800+
721801 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
722807 file <- openFile filePath write_flags "w"
723808 if file == nullPtr
724809 then throwIO $ YamlException $ "could not open file for write: " ++ filePath
@@ -756,7 +841,7 @@ runEmitter opts allocI closeI =
756841 loop = await >>= maybe (close ()) push
757842
758843 push e = do
759− _ <- liftIO $ toEventRaw e $ c_yaml_emitter_emit emitter
844+ _ <- liftIO $ toEventRaw opts e $ c_yaml_emitter_emit emitter
760845 loop
761846 close u = liftIO $ closeI u a
762847
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
22
33flags:
44 yaml:
55 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 @@
11# ChangeLog for yaml
22
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+
387## 0.10.3.0
488
589* 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 @@
11name: yaml
2−version: 0.10.3.0
2+version: 0.11.11.2
33synopsis: Support for parsing and rendering YAML documents.
44description: README and API documentation are available at <https://www.stackage.org/package/yaml>
55category: Data
@@ -10,10 +10,6 @@ github: snoyberg/yaml
1010stability: stable
1111
1212extra-source-files:
13−- c/helper.h
14−- libyaml/yaml_private.h
15−- libyaml/yaml.h
16−- libyaml/LICENSE
1713- test/largest-string.yaml
1814- test/json.yaml
1915- test/resources/foo.yaml
@@ -36,71 +32,39 @@ flags:
3632 description: don't build the examples
3733 manual: false
3834 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
4735
4836dependencies:
49−- base >=4.9.1 && <5 # GHC 8.0.2 and later
37+- base >=4.14 && <5 # GHC 8.10.1 and later
5038- bytestring >=0.9.1.4
5139- transformers >=0.1
5240- mtl
5341- conduit >=1.2.8 && <1.4
54−- resourcet >=0.3 && <1.3
42+- resourcet >=0.3 && <1.4
5543- aeson >=0.11
5644- containers
5745- unordered-containers
5846- vector
5947- text
6048- attoparsec >=0.11.3.0
61−- scientific
49+- scientific >= 0.3 # for Data.ByteString.Builder.Scientific
6250- filepath
6351- directory
6452- template-haskell
65−when:
66− condition: "!impl(ghc >= 8.0)"
67− dependencies:
68− - semigroups
53+- libyaml >=0.1 && <0.2
54+
55+ghc-options: -Wall -Wcompat
6956
7057library:
71− c-sources: c/helper.c
7258 other-extensions:
7359 - LambdaCase
74− ghc-options: -Wall
75− include-dirs:
76− - c
7760 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
9861
9962executables:
10063 json2yaml:
10164 main: json2yaml.hs
10265 source-dirs: exe
10366 dependencies:
67+ - optparse-applicative
10468 - yaml
10569 when:
10670 - condition: flag(no-exe)
@@ -109,14 +73,18 @@ executables:
10973 main: yaml2json.hs
11074 source-dirs: exe
11175 dependencies:
76+ - optparse-applicative
11277 - yaml
11378 when:
11479 - condition: flag(no-exe)
11580 buildable: false
81+ other-extensions:
82+ - CPP
83+ - LambdaCase
84+ - NamedFieldPuns
11685 examples:
11786 main: Main.hs
11887 source-dirs: examples
119− ghc-options: -Wall
12088 when:
12189 - condition: flag(no-examples)
12290 then:
@@ -130,7 +98,7 @@ tests:
13098 spec:
13199 main: Spec.hs
132100 source-dirs: test
133− ghc-options: -Wall "-with-rtsopts=-K1K"
101+ ghc-options: "-with-rtsopts=-K1K"
134102 cpp-options: -DTEST
135103 dependencies:
136104 - hspec >=1.3
@@ -141,3 +109,5 @@ tests:
141109 - base-compat
142110 - temporary
143111 - 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
3737 , decodeFileWithWarnings
3838 , decodeThrow
3939 , 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
4050 -- ** More control over decoding
4151 , decodeHelper
4252 -- * Types
@@ -72,6 +82,7 @@ module Data.Yaml
7282 , isSpecialString
7383 , EncodeOptions
7484 , defaultEncodeOptions
85+ , defaultStringStyle
7586 , setStringStyle
7687 , setFormat
7788 , FormatOptions
@@ -94,22 +105,10 @@ import Data.Aeson
94105 , Object, Array
95106 , withObject, withText, withArray, withScientific, withBool
96107 )
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)
103109import Data.ByteString (ByteString)
104110import Data.Conduit ((.|), runConduitRes)
105111import 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)
113112import qualified Data.Vector as V
114113import System.IO.Unsafe (unsafePerformIO)
115114import Data.Text (Text)
@@ -118,13 +117,6 @@ import Data.Yaml.Internal
118117import Text.Libyaml hiding (encode, decode, encodeFile, decodeFile, encodeWith, encodeFileWith)
119118import qualified Text.Libyaml as Y
120119
121−-- |
122−-- @since 0.10.2.0
123−data EncodeOptions = EncodeOptions
124− { encodeOptionsStringStyle :: Text -> ( Tag, Style )
125− , encodeOptionsFormat :: FormatOptions
126− }
127−
128120-- | Set the string style in the encoded YAML. This is a function that decides
129121-- for each string the type of YAML string to output.
130122--
@@ -149,25 +141,18 @@ setStringStyle s opts = opts { encodeOptionsStringStyle = s }
149141setFormat :: FormatOptions -> EncodeOptions -> EncodeOptions
150142setFormat f opts = opts { encodeOptionsFormat = f }
151143
152−-- | Determine whether a string must be quoted in YAML and can't appear as plain text.
153−-- Useful if you want to use 'setStringStyle'.
154−--
144+-- |
155145-- @since 0.10.2.0
156−isSpecialString :: Text -> Bool
157−isSpecialString s = s `HashSet.member` specialStrings || isNumeric s
146+data EncodeOptions = EncodeOptions
147+ { encodeOptionsStringStyle :: Text -> ( Tag, Style )
148+ , encodeOptionsFormat :: FormatOptions
149+ }
158150
159151-- |
160152-- @since 0.10.2.0
161153defaultEncodeOptions :: EncodeOptions
162154defaultEncodeOptions = EncodeOptions
163− { encodeOptionsStringStyle = \s ->
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 )
155+ { encodeOptionsStringStyle = defaultStringStyle
171156 , encodeOptionsFormat = defaultFormatOptions
172157 }
173158
@@ -180,7 +165,7 @@ encode = encodeWith defaultEncodeOptions
180165-- @since 0.10.2.0
181166encodeWith :: ToJSON a => EncodeOptions -> a -> ByteString
182167encodeWith opts obj = unsafePerformIO $ runConduitRes
183− $ CL.sourceList (objToEvents opts $ toJSON obj)
168+ $ CL.sourceList (objToStream (encodeOptionsStringStyle opts) $ toJSON obj)
184169 .| Y.encodeWith (encodeOptionsFormat opts)
185170
186171-- | Encode a value into its YAML representation and save to the given file.
@@ -192,46 +177,9 @@ encodeFile = encodeFileWith defaultEncodeOptions
192177-- @since 0.10.2.0
193178encodeFileWith :: ToJSON a => EncodeOptions -> FilePath -> a -> IO ()
194179encodeFileWith opts fp obj = runConduitRes
195− $ CL.sourceList (objToEvents opts $ toJSON obj)
180+ $ CL.sourceList (objToStream (encodeOptionsStringStyle opts) $ toJSON obj)
196181 .| Y.encodeFileWith (encodeOptionsFormat opts) fp
197182
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−
235183decode :: FromJSON a
236184 => ByteString
237185 -> Maybe a
@@ -255,6 +203,15 @@ decodeFileEither
255203 -> IO (Either ParseException a)
256204decodeFileEither = fmap (fmap snd) . decodeFileWithWarnings
257205
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+
258215-- | A version of `decodeFileEither` that returns warnings along with the parse
259216-- result.
260217--
@@ -265,6 +222,15 @@ decodeFileWithWarnings
265222 -> IO (Either ParseException ([Warning], a))
266223decodeFileWithWarnings = decodeHelper_ . Y.decodeFile
267224
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+
268234decodeEither :: FromJSON a => ByteString -> Either String a
269235decodeEither bs = unsafePerformIO
270236 $ either (Left . prettyPrintParseException) id
@@ -280,21 +246,47 @@ decodeEither' = either Left (either (Left . AesonException) Right)
280246 . fmap (fmap snd) . decodeHelper
281247 . Y.decode
282248
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+
283258-- | A version of 'decodeEither'' lifted to MonadThrow
284259--
285260-- @since 0.8.31
286261decodeThrow :: (MonadThrow m, FromJSON a) => ByteString -> m a
287262decodeThrow = either throwM return . decodeEither'
288263
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+
289270-- | A version of 'decodeFileEither' lifted to MonadIO
290271--
291272-- @since 0.8.31
292273decodeFileThrow :: (MonadIO m, FromJSON a) => FilePath -> m a
293274decodeFileThrow f = liftIO $ decodeFileEither f >>= either throwIO return
294275
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+
295282-- | Construct a new 'Value' from a list of 'Value's.
296283array :: [Value] -> Value
297284array = Array . V.fromList
298285
286+#if MIN_VERSION_base(4, 13, 0)
287+parseMonad :: MonadFail m => (a -> Parser b) -> a -> m b
288+#else
299289parseMonad :: Monad m => (a -> Parser b) -> a -> m b
290+#endif
300291parseMonad 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
99 , mapping
1010 , namedMapping
1111 , maybeNamedMapping
12+ , mappingComplex
13+ , namedMappingComplex
14+ , maybeNamedMappingComplex
1215 , array
1316 , namedArray
1417 , maybeNamedArray
@@ -37,7 +40,6 @@ module Data.Yaml.Builder
3740
3841import Prelude hiding (null)
3942
40−import Control.Arrow (second)
4143#if MIN_VERSION_aeson(1,0,0)
4244import Data.Aeson.Text (encodeToTextBuilder)
4345#else
@@ -47,10 +49,9 @@ import Data.Aeson.Types (Value(..))
4749import Data.ByteString (ByteString)
4850import qualified Data.ByteString.Char8 as S8
4951import Data.Conduit
50−import qualified Data.HashSet as HashSet
5152import Data.Scientific (Scientific)
5253import Data.Text (Text, unpack)
53−import Data.Text.Encoding (encodeUtf8)
54+import qualified Data.Text as T
5455import qualified Data.Text.Encoding as TE
5556import qualified Data.Text.Lazy as TL
5657import Data.Text.Lazy.Builder (toLazyText)
@@ -68,119 +69,148 @@ class ToYaml a where
6869 toYaml :: a -> YamlBuilder
6970instance ToYaml YamlBuilder where
7071 toYaml = id
71−instance ToYaml a => ToYaml [(Text, a)] where
72− toYaml = mapping . map (second toYaml)
72+instance (ToYaml a, ToYaml b) => ToYaml [(a, b)] where
73+ toYaml = mappingComplex . map (\(k, v) -> (toYaml k, toYaml v))
7374instance ToYaml a => ToYaml [a] where
7475 toYaml = array . map toYaml
7576instance ToYaml Text where
7677 toYaml = string
78+instance {-# OVERLAPPING #-} ToYaml String where
79+ toYaml = string . T.pack
7780instance 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
7990
8091-- |
81−-- @since 0.11.0
92+-- @since 0.10.3.0
8293maybeNamedMapping :: Maybe Text -> [(Text, YamlBuilder)] -> YamlBuilder
83−maybeNamedMapping anchor pairs = YamlBuilder $ \rest ->
84− EventMappingStart NoTag AnyMapping (unpack <$> anchor) : foldr addPair (EventMappingEnd : rest) pairs
94+maybeNamedMapping anchor pairs = maybeNamedMappingComplex anchor complexPairs
8595 where
86− addPair (key, YamlBuilder value) after
87− = EventScalar (encodeUtf8 key) StrTag PlainNoTag Nothing
88− : value after
96+ complexPairs = map (\(k, v) -> (string k, v)) pairs
8997
98+-- |
99+-- @since 0.8.7
90100mapping :: [(Text, YamlBuilder)] -> YamlBuilder
91101mapping = maybeNamedMapping Nothing
92102
93103-- |
94−-- @since 0.11.0
104+-- @since 0.10.3.0
95105namedMapping :: Text -> [(Text, YamlBuilder)] -> YamlBuilder
96106namedMapping name = maybeNamedMapping $ Just name
97107
98108-- |
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
100128maybeNamedArray :: Maybe Text -> [YamlBuilder] -> YamlBuilder
101129maybeNamedArray anchor bs =
102130 YamlBuilder $ (EventSequenceStart NoTag AnySequence (unpack <$> anchor):) . flip (foldr go) bs . (EventSequenceEnd:)
103131 where
104132 go (YamlBuilder b) = b
105133
134+-- |
135+-- @since 0.8.7
106136array :: [YamlBuilder] -> YamlBuilder
107137array = maybeNamedArray Nothing
108138
109139-- |
110−-- @since 0.11.0
140+-- @since 0.10.3.0
111141namedArray :: Text -> [YamlBuilder] -> YamlBuilder
112142namedArray name = maybeNamedArray $ Just name
113143
114144-- |
115−-- @since 0.11.0
145+-- @since 0.10.3.0
116146maybeNamedString :: 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) :)
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
147+maybeNamedString anchor s = YamlBuilder (stringScalar defaultStringStyle anchor s :)
128148
149+-- |
150+-- @since 0.8.7
129151string :: Text -> YamlBuilder
130152string = maybeNamedString Nothing
131153
132154-- |
133−-- @since 0.11.0
155+-- @since 0.10.3.0
134156namedString :: Text -> Text -> YamlBuilder
135157namedString name = maybeNamedString $ Just name
136158
137159-- Use aeson's implementation which gets rid of annoying decimal points
138160-- |
139−-- @since 0.11.0
161+-- @since 0.10.3.0
140162maybeNamedScientific :: 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) :)
142164
165+-- |
166+-- @since 0.8.13
143167scientific :: Scientific -> YamlBuilder
144168scientific = maybeNamedScientific Nothing
145169
146170-- |
147−-- @since 0.11.0
171+-- @since 0.10.3.0
148172namedScientific :: Text -> Scientific -> YamlBuilder
149173namedScientific name = maybeNamedScientific $ Just name
150174
175+-- |
176+-- @since 0.8.13
151177{-# DEPRECATED number "Use scientific" #-}
152178number :: Scientific -> YamlBuilder
153179number = scientific
154180
155181-- |
156−-- @since 0.11.0
182+-- @since 0.10.3.0
157183maybeNamedBool :: Maybe Text -> Bool -> YamlBuilder
158−maybeNamedBool anchor True = YamlBuilder (EventScalar "true" BoolTag PlainNoTag (unpack <$> anchor) :)
159−maybeNamedBool anchor False = YamlBuilder (EventScalar "false" BoolTag PlainNoTag (unpack <$> anchor) :)
184+maybeNamedBool anchor True = YamlBuilder (EventScalar "true" NoTag PlainNoTag (unpack <$> anchor) :)
185+maybeNamedBool anchor False = YamlBuilder (EventScalar "false" NoTag PlainNoTag (unpack <$> anchor) :)
160186
187+-- |
188+-- @since 0.8.13
161189bool :: Bool -> YamlBuilder
162190bool = maybeNamedBool Nothing
163191
164192-- |
165−-- @since 0.11.0
193+-- @since 0.10.3.0
166194namedBool :: Text -> Bool -> YamlBuilder
167195namedBool name = maybeNamedBool $ Just name
168196
169197-- |
170−-- @since 0.11.0
198+-- @since 0.10.3.0
171199maybeNamedNull :: Maybe Text -> YamlBuilder
172−maybeNamedNull anchor = YamlBuilder (EventScalar "null" NullTag PlainNoTag (unpack <$> anchor) :)
200+maybeNamedNull anchor = YamlBuilder (EventScalar "null" NoTag PlainNoTag (unpack <$> anchor) :)
173201
202+-- |
203+-- @since 0.8.13
174204null :: YamlBuilder
175205null = maybeNamedNull Nothing
176206
177207-- |
178−-- @since 0.11.0
208+-- @since 0.10.3.0
179209namedNull :: Text -> YamlBuilder
180210namedNull name = maybeNamedNull $ Just name
181211
182212-- |
183−-- @since 0.11.0
213+-- @since 0.10.3.0
184214alias :: Text -> YamlBuilder
185215alias anchor = YamlBuilder (EventAlias (unpack anchor) :)
186216
@@ -191,6 +221,8 @@ toEvents (YamlBuilder front) =
191221toSource :: (Monad m, ToYaml a) => a -> ConduitM i Event m ()
192222toSource = mapM_ yield . toEvents . toYaml
193223
224+-- |
225+-- @since 0.8.7
194226toByteString :: ToYaml a => a -> ByteString
195227toByteString = toByteStringWith defaultFormatOptions
196228
src/Data/Yaml/Config.hs → yaml/src/Data/Yaml/Config.hsrenamed+34−15
@@ -5,7 +5,7 @@
55-- In particular, merging environment variables with yaml values
66--
77-- '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@.
99--
1010-- On a historical note, this code was taken directly from the yesod web framework's configuration module.
1111module Data.Yaml.Config
@@ -33,7 +33,13 @@ import Data.Monoid
3333import Data.Semigroup
3434import Data.List.NonEmpty (nonEmpty)
3535import 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
3641import qualified Data.HashMap.Strict as H
42+#endif
3743import Data.Text (Text, pack)
3844import System.Environment (getArgs, getEnvironment)
3945import Control.Arrow ((***))
@@ -45,6 +51,16 @@ import qualified Data.Yaml.Include as YI
4551import Data.Maybe (fromMaybe)
4652import qualified Data.Text as T
4753
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+
4864newtype MergedValue = MergedValue { getMergedValue :: Value }
4965
5066instance Semigroup MergedValue where
@@ -64,7 +80,7 @@ mergeValues x _ = x
6480--
6581-- @since 0.8.16
6682applyEnvValue :: Bool -- ^ require an environment variable to be present?
67− -> H.HashMap Text Text -> Value -> Value
83+ -> KeyMap Text -> Value -> Value
6884applyEnvValue requireEnv' env =
6985 goV
7086 where
@@ -74,7 +90,7 @@ applyEnvValue requireEnv' env =
7490 t2 <- T.stripPrefix "_env:" t1
7591 let (name, t3) = T.break (== ':') t2
7692 mdef = fmap parseValue $ T.stripPrefix ":" t3
77− Just $ case H.lookup name env of
93+ Just $ case H.lookup (fromText name) env of
7894 Just val ->
7995 -- If the default value parses as a String, we treat the
8096 -- environment variable as a raw value and do not parse it.
@@ -101,8 +117,8 @@ applyEnvValue requireEnv' env =
101117-- | Get the actual environment as a @HashMap@ from @Text@ to @Text@.
102118--
103119-- @since 0.8.16
104−getCurrentEnv :: IO (H.HashMap Text Text)
105−getCurrentEnv = fmap (H.fromList . map (pack *** pack)) getEnvironment
120+getCurrentEnv :: IO (KeyMap Text)
121+getCurrentEnv = fmap (H.fromList . map (fromText . pack *** pack)) getEnvironment
106122
107123-- | A convenience wrapper around 'applyEnvValue' and 'getCurrentEnv'
108124--
@@ -118,8 +134,8 @@ applyCurrentEnv requireEnv' orig = flip (applyEnvValue requireEnv') orig <$> get
118134data EnvUsage = IgnoreEnv
119135 | UseEnv
120136 | RequireEnv
121− | UseCustomEnv (H.HashMap Text Text)
122− | RequireCustomEnv (H.HashMap Text Text)
137+ | UseCustomEnv (KeyMap Text)
138+ | RequireCustomEnv (KeyMap Text)
123139
124140-- | Do not use any environment variables, instead relying on defaults values
125141-- in the config file.
@@ -146,14 +162,14 @@ requireEnv = RequireEnv
146162-- @HashMap@ as the environment.
147163--
148164-- @since 0.8.16
149−useCustomEnv :: H.HashMap Text Text -> EnvUsage
165+useCustomEnv :: KeyMap Text -> EnvUsage
150166useCustomEnv = UseCustomEnv
151167
152168-- | Same as 'requireEnv', but instead of the actual environment, use the
153169-- provided @HashMap@ as the environment.
154170--
155171-- @since 0.8.16
156−requireCustomEnv :: H.HashMap Text Text -> EnvUsage
172+requireCustomEnv :: KeyMap Text -> EnvUsage
157173requireCustomEnv = RequireCustomEnv
158174
159175-- | Load the settings from the following three sources:
@@ -169,6 +185,11 @@ requireCustomEnv = RequireCustomEnv
169185--
170186-- > loadYamlSettings ["config/foo.yaml"] [] useEnv
171187--
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+--
172193-- @since 0.8.16
173194loadYamlSettings
174195 :: FromJSON settings
@@ -180,9 +201,7 @@ loadYamlSettings runTimeFiles compileValues envUsage = do
180201 runValues <- forM runTimeFiles $ \fp -> do
181202 eres <- YI.decodeFileEither fp
182203 case eres of
183− Left e -> do
184− putStrLn $ "loadYamlSettings: Could not parse file as YAML: " ++ fp
185− throwIO e
204+ Left e -> throwIO (Y.LoadSettingsException fp e)
186205 Right value -> return value
187206
188207 value' <-
@@ -197,9 +216,9 @@ loadYamlSettings runTimeFiles compileValues envUsage = do
197216 UseCustomEnv env -> return $ applyEnvValue False env value'
198217 RequireCustomEnv env -> return $ applyEnvValue True env value'
199218
200− case fromJSON value of
201− Error s -> error $ "Could not convert to expected type: " ++ s
202− Success settings -> return settings
219+ case Y.parseEither parseJSON value of
220+ Left s -> error $ "Could not convert to expected type: " ++ s
221+ Right settings -> return settings
203222
204223-- | Same as @loadYamlSettings@, but get the list of runtime config files from
205224-- 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
99 , prettyPrintParseException
1010 , Warning(..)
1111 , parse
12+ , Parse
1213 , decodeHelper
1314 , decodeHelper_
15+ , decodeAllHelper
16+ , decodeAllHelper_
17+ , textToScientific
18+ , stringScalar
19+ , StringStyle
20+ , defaultStringStyle
21+ , isSpecialString
1422 , specialStrings
1523 , isNumeric
16− , textToScientific
24+ , objToStream
25+ , objToEvents
1726 ) where
1827
1928#if !MIN_VERSION_base(4,8,0)
@@ -25,43 +34,81 @@ import Control.Monad (when, unless)
2534import Control.Monad.Trans.Resource (ResourceT, runResourceT)
2635import Control.Monad.State.Strict
2736import Control.Monad.Reader
37+#if MIN_VERSION_aeson(2,1,2)
38+import Data.Aeson hiding (AesonException)
39+#else
2840import 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
3052import Data.Aeson.Types hiding (parse)
53+import Data.Aeson.Internal (JSONPath, JSONPathElement(..), formatError)
54+#endif
3155import qualified Data.Attoparsec.Text as Atto
3256import Data.Bits (shiftL, (.|.))
3357import 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)
3461import Data.Char (toUpper, ord)
35−import Data.List
62+import qualified Data.List as List
3663import Data.Conduit ((.|), ConduitM, runConduit)
3764import qualified Data.Conduit.List as CL
38−import qualified Data.HashMap.Strict as M
3965import qualified Data.HashSet as HashSet
4066import Data.Map (Map)
4167import qualified Data.Map as Map
4268import Data.Set (Set)
4369import qualified Data.Set as Set
44−import Data.Scientific (Scientific)
45−import Data.Text (Text, pack)
70+import Data.Scientific (Scientific, base10Exponent, coefficient)
71+import Data.Text (Text)
4672import qualified Data.Text as T
47−import Data.Text.Encoding (decodeUtf8With)
73+import Data.Text.Encoding (decodeUtf8With, encodeUtf8)
4874import Data.Text.Encoding.Error (lenientDecode)
4975import Data.Typeable
5076import qualified Data.Vector as V
77+import Data.Void (Void)
5178
5279import qualified Text.Libyaml as Y
5380import Text.Libyaml hiding (encode, decode, encodeFile, decodeFile)
5481
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+
5599data ParseException = NonScalarKey
56100 | UnknownAlias { _anchorName :: Y.AnchorName }
57101 | UnexpectedEvent { _received :: Maybe Event
58102 , _expected :: Maybe Event
59103 }
60104 | InvalidYaml (Maybe YamlException)
105+ | MultipleDocuments
61106 | AesonException String
62107 | OtherParseException SomeException
108+ | NonStringKey JSONPath
63109 | NonStringKeyAlias Y.AnchorName Value
64110 | CyclicIncludes
111+ | LoadSettingsException FilePath ParseException
65112 deriving (Show, Typeable)
66113
67114instance Exception ParseException where
@@ -105,14 +152,17 @@ prettyPrintParseException pe = case pe of
105152 _ -> ",\n" ++ context ++ ":\n"
106153 , problem
107154 ]
155+ MultipleDocuments -> "Multiple YAML documents encountered"
108156 AesonException s -> "Aeson exception:\n" ++ s
109157 OtherParseException exc -> "Generic parse exception:\n" ++ show exc
158+ NonStringKey path -> formatError path "Non-string keys are not supported"
110159 NonStringKeyAlias anchor value -> unlines
111160 [ "Non-string key alias:"
112161 , " Anchor name: " ++ anchor
113162 , " Value: " ++ show value
114163 ]
115164 CyclicIncludes -> "Cyclic includes"
165+ LoadSettingsException fp exc -> "Could not parse file as YAML: " ++ fp ++ "\n" ++ prettyPrintParseException exc
116166
117167defineAnchor :: Value -> String -> ReaderT JSONPath (ConduitM e o Parse) ()
118168defineAnchor value name = modify (modifyAnchors $ Map.insert name value)
@@ -146,24 +196,34 @@ requireEvent e = do
146196
147197parse :: ReaderT JSONPath (ConduitM Event o Parse) Value
148198parse = 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
149207 streamStart <- lift CL.head
150208 case streamStart of
151209 Nothing ->
152210 -- empty string input
153− return Null
154− Just EventStreamStart -> do
155− documentStart <- lift CL.head
156− case documentStart of
157− Just EventStreamEnd ->
158− -- empty file input, comment only string/file input
159− return Null
160− Just EventDocumentStart -> do
161− res <- parseO
162− requireEvent EventDocumentEnd
163− requireEvent EventStreamEnd
164− return res
165− _ -> liftIO $ throwIO $ UnexpectedEvent documentStart Nothing
166− _ -> liftIO $ throwIO $ UnexpectedEvent streamStart Nothing
211+ return []
212+ Just EventStreamStart ->
213+ -- empty file input, comment only string/file input
214+ parseDocs
215+ _ -> missed streamStart
216+ where
217+ parseDocs = do
218+ documentStart <- lift CL.head
219+ case documentStart of
220+ Just EventStreamEnd -> return []
221+ Just EventDocumentStart -> do
222+ res <- parseO
223+ requireEvent EventDocumentEnd
224+ (res :) <$> parseDocs
225+ _ -> missed documentStart
226+ missed event = liftIO $ throwIO $ UnexpectedEvent event Nothing
167227
168228parseScalar :: ByteString -> Anchor -> Style -> Tag
169229 -> ReaderT JSONPath (ConduitM Event o Parse) Text
@@ -228,9 +288,9 @@ parseS !n a front = do
228288 o <- local (Index n :) parseO
229289 parseS (succ n) a $ front . (:) o
230290
231−parseM :: Set Text
291+parseM :: Set Key
232292 -> Y.Anchor
233− -> M.HashMap Text Value
293+ -> KeyMap Value
234294 -> ReaderT JSONPath (ConduitM Event o Parse) Value
235295parseM mergedKeys a front = do
236296 me <- lift CL.head
@@ -241,14 +301,16 @@ parseM mergedKeys a front = do
241301 return res
242302 _ -> do
243303 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
245305 Just (EventAlias an) -> do
246306 m <- lookupAnchor an
247307 case m of
248308 Nothing -> liftIO $ throwIO $ UnknownAlias an
249− Just (String t) -> return t
309+ Just (String t) -> return $ fromText t
250310 Just v -> liftIO $ throwIO $ NonStringKeyAlias an v
251− _ -> liftIO $ throwIO $ UnexpectedEvent me Nothing
311+ _ -> do
312+ path <- ask
313+ liftIO $ throwIO $ NonStringKey path
252314
253315 (mergedKeys', al') <- local (Key s :) $ do
254316 o <- parseO
@@ -257,52 +319,151 @@ parseM mergedKeys a front = do
257319 path <- reverse <$> ask
258320 addWarning (DuplicateKey path)
259321 return (Set.delete s mergedKeys, M.insert s o front)
260− if s == pack "<<"
322+ if s == "<<"
261323 then case o of
262324 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
264326 _ -> al
265327 else al
266328 parseM mergedKeys' a al'
267329 where mergeObjects al (Object om) = M.union al om
268330 mergeObjects al _ = al
269331
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+ ]
271353
272354decodeHelper :: FromJSON a
273355 => ConduitM () Y.Event Parse ()
274356 -> IO (Either ParseException ([Warning], Either String a))
275−decodeHelper src = do
276− -- This used to be tryAny, but the fact is that catching async
277− -- exceptions is fine here. We'll rethrow them immediately in the
278− -- otherwise clause.
279− x <- try $ runResourceT $ runStateT (runConduit $ src .| runReaderT parse []) (ParseState Map.empty [])
280− case x of
281− Left e
282− | Just pe <- fromException e -> return $ Left pe
283− | Just ye <- fromException e -> return $ Left $ InvalidYaml $ Just (ye :: YamlException)
284− | otherwise -> throwIO e
285− Right (y, st) -> return $ Right (parseStateWarnings st, parseEither parseJSON y)
357+decodeHelper = mkHelper parse throwIO $ \(v, st) ->
358+ Right (parseStateWarnings st, parseEither parseJSON v)
359+
360+decodeAllHelper :: FromJSON a
361+ => ConduitM () Event Parse ()
362+ -> IO (Either ParseException ([Warning], Either String [a]))
363+decodeAllHelper = mkHelper parseAll throwIO $ \(vs, st) ->
364+ Right (parseStateWarnings st, mapM (parseEither parseJSON) vs)
365+
366+catchLeft :: SomeException -> IO (Either ParseException a)
367+catchLeft = return . Left . OtherParseException
286368
287369decodeHelper_ :: FromJSON a
288370 => ConduitM () Event Parse ()
289371 -> IO (Either ParseException ([Warning], a))
290−decodeHelper_ src = do
291− x <- try $ runResourceT $ runStateT (runConduit $ src .| runReaderT parse []) (ParseState Map.empty [])
292− return $ case x of
293− Left e
294− | Just pe <- fromException e -> Left pe
295− | Just ye <- fromException e -> Left $ InvalidYaml $ Just (ye :: YamlException)
296− | otherwise -> Left $ OtherParseException e
297− Right (y, st) -> either
298− (Left . AesonException)
299− Right
300− ((,) (parseStateWarnings st) <$> parseEither parseJSON y)
372+decodeHelper_ = mkHelper parse catchLeft $ \(v, st) ->
373+ case parseEither parseJSON v of
374+ Left e -> Left $ AesonException e
375+ Right x -> Right (parseStateWarnings st, x)
376+
377+decodeAllHelper_ :: FromJSON a
378+ => ConduitM () Event Parse ()
379+ -> IO (Either ParseException ([Warning], [a]))
380+decodeAllHelper_ = mkHelper parseAll catchLeft $ \(vs, st) ->
381+ case mapM (parseEither parseJSON) vs of
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
301413
302414-- | Strings which must be escaped so as not to be treated as non-string scalars.
415+--
416+-- @since 0.8.32
303417specialStrings :: HashSet.HashSet Text
304418specialStrings = HashSet.fromList $ T.words
305419 "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 ~ *"
306420
421+-- |
422+-- @since 0.8.32
307423isNumeric :: Text -> Bool
308424isNumeric = 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
5252 case f am of
5353 Left t -> Left t
5454 Right x -> unYamlParser (g x) am
55+#if MIN_VERSION_base(4,13,0)
56+instance MonadFail YamlParser where
57+#endif
5558 fail = YamlParser . const . Left . pack
5659instance MonadPlus YamlParser where
5760 mzero = fail "mzero"
src/Data/Yaml/Pretty.hs → yaml/src/Data/Yaml/Pretty.hsrenamed+20−3
@@ -10,6 +10,7 @@ module Data.Yaml.Pretty
1010 , getConfDropNull
1111 , setConfDropNull
1212 , defConfig
13+ , pretty
1314 ) where
1415
1516import Prelude hiding (null)
@@ -17,10 +18,16 @@ import Prelude hiding (null)
1718#if !MIN_VERSION_base(4,8,0)
1819import Control.Applicative ((<$>))
1920#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
2028import Data.Aeson.Types
2129import Data.ByteString (ByteString)
2230import Data.Function (on)
23−import qualified Data.HashMap.Strict as HM
2431import Data.List (sortBy)
2532#if !MIN_VERSION_base(4,8,0)
2633import Data.Monoid
@@ -30,11 +37,21 @@ import qualified Data.Vector as V
3037
3138import Data.Yaml.Builder
3239
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+
3350-- |
3451-- @since 0.8.13
3552data Config = Config
3653 { confCompare :: Text -> Text -> Ordering -- ^ Function used to sort keys in objects
37− , confDropNull :: Bool
54+ , confDropNull :: Bool -- ^ Drop null values from objects
3855 }
3956
4057-- | The default configuration: do not sort objects or drop keys
@@ -71,7 +88,7 @@ pretty cfg = go
7188 select
7289 | confDropNull cfg = HM.filter (/= Null)
7390 | 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)
7592 go (Array a) = array (go <$> V.toList a)
7693 go Null = null
7794 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 #-}
12{-# LANGUAGE QuasiQuotes #-}
23{-# LANGUAGE OverloadedStrings #-}
34module Data.Yaml.IncludeSpec (main, spec) where
@@ -6,7 +7,11 @@ import Test.Hspec
67import Data.List (isPrefixOf)
78import qualified Data.ByteString.Lazy as LB
89import Data.Aeson
10+#if MIN_VERSION_aeson(2,2,0)
11+import Data.Aeson.Types (JSONPathElement(..))
12+#else
913import Data.Aeson.Internal (JSONPathElement(..))
14+#endif
1015import Data.Yaml (ParseException(InvalidYaml))
1116import Data.Yaml.Include
1217import 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 @@
88module Data.YamlSpec (main, spec) where
99
1010import qualified Text.Libyaml as Y
11+import qualified Data.ByteString as BS
1112import qualified Data.ByteString.Char8 as B8
1213import Data.Int (Int64)
14+import qualified Data.Scientific as S
1315
1416import Test.HUnit hiding (Test, path)
1517
@@ -19,18 +21,29 @@ import qualified Data.Conduit.List as CL
1921import Control.Monad
2022import Control.Exception (try, SomeException)
2123import Test.Hspec
24+import Test.Hspec.QuickCheck
2225import Data.Either.Compat
2326import System.Directory (createDirectory, createDirectoryIfMissing)
2427import Test.Mockery.Directory
2528
2629import qualified Data.Yaml as D
30+import qualified Data.Yaml.Builder as B
31+import qualified Data.Yaml.Internal as Internal
2732import qualified Data.Yaml.Pretty as Pretty
2833import Data.Yaml (object, array, (.=))
2934import 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
3041import qualified Data.HashMap.Strict as M
42+#endif
3143import qualified Data.Text as T
3244import Data.Aeson.TH
3345import Data.Scientific (Scientific)
46+import Data.String (fromString)
3447import Data.Text (Text)
3548import Data.Text.Encoding (decodeUtf8, encodeUtf8)
3649import Data.Vector (Vector)
@@ -40,6 +53,23 @@ import qualified Data.HashMap.Strict as HM
4053import System.IO (hClose)
4154import System.IO.Temp (withSystemTempFile)
4255
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+
4373data TestJSON = TestJSON
4474 { string :: Text
4575 , number :: Int
@@ -50,10 +80,44 @@ data TestJSON = TestJSON
5080
5181deriveJSON defaultOptions ''TestJSON
5282
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+
5392shouldDecode :: (Show a, D.FromJSON a, Eq a) => B8.ByteString -> a -> IO ()
5493shouldDecode bs expected = do
55− actual <- D.decodeThrow bs
56− actual `shouldBe` expected
94+ actual <- D.decodeThrow bs
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]
57121
58122main :: IO ()
59123main = hspec spec
@@ -76,6 +140,7 @@ spec = do
76140 it "count scalars" caseCountScalars
77141 it "largest string" caseLargestString
78142 it "encode/decode" caseEncodeDecode
143+ it "encode/decode events" caseEncodeDecodeEvents
79144 it "encode/decode file" caseEncodeDecodeFile
80145 it "interleaved encode/decode" caseInterleave
81146 it "decode invalid document (without segfault)" caseDecodeInvalidDocument
@@ -91,6 +156,9 @@ spec = do
91156 it "encode/decode" caseEncodeDecodeDataPretty
92157 it "encode/decode strings" caseEncodeDecodeStringsPretty
93158 it "processes datatypes" caseDataTypesPretty
159+ describe "Data.Yaml.Builder" $ do
160+ it "encode/decode" caseEncodeDecodeDataBuilder
161+ it "encode/decode complex mapping" caseEncodeDecodeComplexMappingBuilder
94162 describe "Data.Yaml aliases" $ do
95163 it "simple scalar alias" caseSimpleScalarAlias
96164 it "simple sequence alias" caseSimpleSequenceAlias
@@ -136,7 +204,7 @@ spec = do
136204
137205 describe "special keys" $ do
138206 let tester key = it (T.unpack key) $
139− let value = object [key .= True]
207+ let value = object [fromText key .= True]
140208 in D.encode value `shouldDecode` value
141209 mapM_ tester specialStrings
142210
@@ -149,18 +217,21 @@ spec = do
149217 describe "decodeFileEither" $ do
150218 it "loads YAML through JSON into Haskell data" $ do
151219 tj <- either (error . show) id `fmap` D.decodeFileEither "test/json.yaml"
152− 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− }
220+ tj `shouldBe` testJSON
159221
160222 context "when file does not exist" $ do
161223 it "returns Left" $ do
162224 (D.decodeFileEither "./does_not_exist.yaml" :: IO (Either D.ParseException D.Value)) >>= (`shouldSatisfy` isLeft)
163225
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]
164235
165236 describe "round-tripping of special scalars" $ do
166237 let special = words "y Y On ON false 12345 12345.0 12345a 12e3"
@@ -178,18 +249,9 @@ spec = do
178249
179250 it "truncates files" caseTruncatesFiles
180251
181− it "quoting keys #137" $ do
182− let keys = T.words "true false NO YES 1.2 1e5 null"
183− bs = D.encode $ M.fromList $ map (, ()) keys
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 ()
252+ it "encode quotes special keys #137" $ caseSpecialKeys D.encode
253+
254+ it "encodePretty quotes special keys #179" $ caseSpecialKeys (Pretty.encodePretty Pretty.defConfig)
193255
194256 describe "non-decimal numbers #135" $ do
195257 let go str val = it str $ encodeUtf8 (T.pack str) `shouldDecode` val
@@ -205,6 +267,110 @@ spec = do
205267 go "12.3015e+02" (1230.15 :: Scientific)
206268 go "1230.15" (1230.15 :: Scientific)
207269
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+
208374specialStrings :: [T.Text]
209375specialStrings =
210376 [ "fo\"o"
@@ -365,6 +531,13 @@ caseEncodeDecode = do
365531 yamlString = "foo: bar\nbaz:\n - bin1\n - bin2\n"
366532 yamlBS = B8.pack yamlString
367533
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+
368541caseEncodeDecodeFile :: Assertion
369542caseEncodeDecodeFile = withFile "" $ \tmpPath -> do
370543 eList <- runConduitRes $ Y.decodeFile filePath .| CL.consume
@@ -403,7 +576,7 @@ mkStrScalar :: String -> D.Value
403576mkStrScalar = D.String . T.pack
404577
405578mappingKey :: 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)
407580mappingKey _ _ = error "expected Object"
408581
409582sample :: D.Value
@@ -414,6 +587,24 @@ sample = array
414587 , ("bar3", D.String "")
415588 ]
416589 , 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
417608 ]
418609
419610caseEncodeDecodeData :: Assertion
@@ -423,6 +614,28 @@ caseEncodeDecodeDataPretty :: Assertion
423614caseEncodeDecodeDataPretty =
424615 Pretty.encodePretty Pretty.defConfig sample `shouldDecode` sample
425616
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+
426639caseEncodeDecodeFileData :: Assertion
427640caseEncodeDecodeFileData = withFile "" $ \fp -> do
428641 D.encodeFile fp sample
@@ -470,7 +683,9 @@ caseSimpleSequenceAlias =
470683caseSimpleMappingAlias :: Assertion
471684caseSimpleMappingAlias =
472685 "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
474689
475690caseMappingAliasBeforeAnchor :: Assertion
476691caseMappingAliasBeforeAnchor =
@@ -607,9 +822,9 @@ casePreservesScientificPrecision = do
607822 -- However, it didn't work (and still doesn't work with aeson < 0.7)
608823 -- for two reasons:
609824 --
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
611826 -- 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
613828 -- results, because of <https://github.com/bos/text/issues/34>.
614829 "x: 9.78159610558926e-5" `shouldDecode` object
615830 [ "x" .= D.Number (read "9.78159610558926e-5") ]
@@ -622,3 +837,63 @@ caseTruncatesFiles = withSystemTempFile "truncate.yaml" $ \fp h -> do
622837 D.encodeFile fp val
623838 res <- D.decodeFileEither fp
624839 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