aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeongik Cha <jeongik@google.com>2023-09-27 08:11:50 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-09-27 08:11:50 +0000
commita4fab8ba166d8c7e43abac77bea137ed3e935447 (patch)
tree4751d9b15c4bf6bc6b012e7fffb8773b1e9d4697
parente6ff902e349bd38b7c8775e23f41f2780527eb08 (diff)
parentd13ba9dfc1437a1824840d743abe1a2e1b513bc7 (diff)
downloadunsafe-libyaml-a4fab8ba166d8c7e43abac77bea137ed3e935447.tar.gz
Import unsafe-libyaml am: d13ba9dfc1
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/unsafe-libyaml/+/2754408 Change-Id: Ic2d3045c179624a657dabcb5394947f252d2e5cb Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--.cargo_vcs_info.json6
-rw-r--r--.github/FUNDING.yml1
-rw-r--r--.github/workflows/ci.yml95
-rw-r--r--.gitignore4
-rw-r--r--Android.bp37
-rw-r--r--Cargo.toml38
-rw-r--r--Cargo.toml.orig24
l---------LICENSE1
-rw-r--r--LICENSE-MIT23
-rw-r--r--METADATA19
-rw-r--r--MODULE_LICENSE_MIT0
-rw-r--r--OWNERS1
-rw-r--r--README.md24
-rw-r--r--src/api.rs1545
-rw-r--r--src/bin/cstr/mod.rs47
-rw-r--r--src/bin/run-emitter-test-suite.rs307
-rw-r--r--src/bin/run-parser-test-suite.rs222
-rw-r--r--src/dumper.rs449
-rw-r--r--src/emitter.rs2384
-rw-r--r--src/lib.rs307
-rw-r--r--src/loader.rs579
-rw-r--r--src/macros.rs514
-rw-r--r--src/parser.rs1353
-rw-r--r--src/reader.rs469
-rw-r--r--src/scanner.rs2663
-rw-r--r--src/success.rs25
-rw-r--r--src/writer.rs148
-rw-r--r--src/yaml.rs1284
-rw-r--r--tests/bin/mod.rs48
-rw-r--r--tests/ignorelist/libyaml-emitter72
-rw-r--r--tests/ignorelist/libyaml-parser34
-rw-r--r--tests/ignorelist/libyaml-parser-error10
-rw-r--r--tests/test_emitter.rs37
-rw-r--r--tests/test_parser.rs32
-rw-r--r--tests/test_parser_error.rs31
35 files changed, 12833 insertions, 0 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..09e6054
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,6 @@
+{
+ "git": {
+ "sha1": "9651508612c804480141a6f57839e7af729559f7"
+ },
+ "path_in_vcs": ""
+} \ No newline at end of file
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..7507077
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+github: dtolnay
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..8661567
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,95 @@
+name: CI
+
+on:
+ push:
+ pull_request:
+ workflow_dispatch:
+ schedule: [cron: "40 1 * * *"]
+
+permissions:
+ contents: read
+
+env:
+ RUSTFLAGS: -Dwarnings
+
+jobs:
+ pre_ci:
+ uses: dtolnay/.github/.github/workflows/pre_ci.yml@master
+
+ test:
+ name: Rust ${{matrix.rust}}
+ needs: pre_ci
+ if: needs.pre_ci.outputs.continue
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ rust: [nightly, beta, stable, 1.62.0]
+ timeout-minutes: 45
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@master
+ with:
+ toolchain: ${{matrix.rust}}
+ - name: Enable type layout randomization
+ run: echo RUSTFLAGS=${RUSTFLAGS}\ -Zrandomize-layout >> $GITHUB_ENV
+ if: matrix.rust == 'nightly'
+ - run: cargo test
+
+ msrv:
+ name: Rust 1.56.0
+ needs: pre_ci
+ if: needs.pre_ci.outputs.continue
+ runs-on: ubuntu-latest
+ timeout-minutes: 45
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@1.56.0
+ - run: cargo check --lib
+
+ clippy:
+ name: Clippy
+ runs-on: ubuntu-latest
+ if: github.event_name != 'pull_request'
+ timeout-minutes: 45
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@clippy
+ - run: cargo clippy --tests -- -Dclippy::all -Dclippy::pedantic
+
+ miri:
+ name: Miri
+ needs: pre_ci
+ if: needs.pre_ci.outputs.continue
+ runs-on: ubuntu-latest
+ timeout-minutes: 45
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@miri
+ - run: cargo miri setup
+ - run: cargo miri test
+ env:
+ MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-strict-provenance
+
+ fuzz:
+ name: Fuzz
+ needs: pre_ci
+ if: needs.pre_ci.outputs.continue
+ runs-on: ubuntu-latest
+ timeout-minutes: 45
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/rust-toolchain@nightly
+ - uses: dtolnay/install@cargo-fuzz
+ - run: cargo fuzz check
+
+ outdated:
+ name: Outdated
+ runs-on: ubuntu-latest
+ if: github.event_name != 'pull_request'
+ timeout-minutes: 45
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dtolnay/install@cargo-outdated
+ - run: cargo outdated --workspace --exit-code 1
+ - run: cargo outdated --manifest-path fuzz/Cargo.toml --exit-code 1
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b3a0655
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+/build.rs
+/rust-toolchain
+target
+Cargo.lock
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..078508e
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,37 @@
+// This file is generated by cargo2android.py --run --force-rlib.
+// Do not modify this file as changes will be overridden on upgrade.
+
+
+
+rust_library_host_rlib {
+ name: "libunsafe_libyaml",
+ crate_name: "unsafe_libyaml",
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.2.9",
+ srcs: ["src/lib.rs"],
+ edition: "2021",
+}
+
+rust_binary_host {
+ name: "run_emitter_test_suite",
+ crate_name: "run_emitter_test_suite",
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.2.9",
+ srcs: ["src/bin/run-emitter-test-suite.rs"],
+ edition: "2021",
+ rustlibs: [
+ "libunsafe_libyaml",
+ ],
+}
+
+rust_binary_host {
+ name: "run_parser_test_suite",
+ crate_name: "run_parser_test_suite",
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.2.9",
+ srcs: ["src/bin/run-parser-test-suite.rs"],
+ edition: "2021",
+ rustlibs: [
+ "libunsafe_libyaml",
+ ],
+}
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..31efefc
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,38 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2021"
+rust-version = "1.56"
+name = "unsafe-libyaml"
+version = "0.2.9"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+description = "libyaml transpiled to rust by c2rust"
+documentation = "https://docs.rs/unsafe-libyaml"
+readme = "README.md"
+keywords = ["yaml"]
+categories = [
+ "encoding",
+ "parser-implementations",
+ "no-std",
+]
+license = "MIT"
+repository = "https://github.com/dtolnay/unsafe-libyaml"
+
+[package.metadata.docs.rs]
+rustdoc-args = ["--generate-link-to-definition"]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+doc-scrape-examples = false
+
+[dev-dependencies.pretty_assertions]
+version = "1.0"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..e6186b8
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,24 @@
+[package]
+name = "unsafe-libyaml"
+version = "0.2.9" # remember to update html_root_url
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+categories = ["encoding", "parser-implementations", "no-std"]
+description = "libyaml transpiled to rust by c2rust"
+documentation = "https://docs.rs/unsafe-libyaml"
+edition = "2021"
+keywords = ["yaml"]
+license = "MIT"
+repository = "https://github.com/dtolnay/unsafe-libyaml"
+rust-version = "1.56"
+
+[workspace]
+[dev-dependencies]
+pretty_assertions = "1.0"
+unsafe-libyaml-test-suite = { path = "tests/data" }
+
+[lib]
+doc-scrape-examples = false
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+rustdoc-args = ["--generate-link-to-definition"]
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..7f9a88e
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+LICENSE-MIT \ No newline at end of file
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..31aa793
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,23 @@
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..ba4f960
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,19 @@
+name: "unsafe-libyaml"
+description: "libyaml transpiled to rust by c2rust"
+third_party {
+ identifier {
+ type: "crates.io"
+ value: "https://crates.io/crates/unsafe-libyaml"
+ }
+ identifier {
+ type: "Archive"
+ value: "https://static.crates.io/crates/unsafe-libyaml/unsafe-libyaml-0.2.9.crate"
+ }
+ version: "0.2.9"
+ license_type: NOTICE
+ last_upgrade_date {
+ year: 2023
+ month: 8
+ day: 23
+ }
+}
diff --git a/MODULE_LICENSE_MIT b/MODULE_LICENSE_MIT
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_MIT
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..45dc4dd
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1 @@
+include platform/prebuilts/rust:master:/OWNERS
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bfe37a7
--- /dev/null
+++ b/README.md
@@ -0,0 +1,24 @@
+unsafe-libyaml
+==============
+
+[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/unsafe--libyaml-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/unsafe-libyaml)
+[<img alt="crates.io" src="https://img.shields.io/crates/v/unsafe-libyaml.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/unsafe-libyaml)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-unsafe--libyaml-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/unsafe-libyaml)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/unsafe-libyaml/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/unsafe-libyaml/actions?query=branch%3Amaster)
+
+This library is [libyaml] translated from C to unsafe Rust with the assistance
+of [c2rust].
+
+[libyaml]: https://github.com/yaml/libyaml/tree/2c891fc7a770e8ba2fec34fc6b545c672beb37e6
+[c2rust]: https://github.com/immunant/c2rust
+
+```toml
+[dependencies]
+unsafe-libyaml = "0.2"
+```
+
+*Compiler support: requires rustc 1.56+*
+
+## License
+
+<a href="LICENSE-MIT">MIT license</a>, same as libyaml.
diff --git a/src/api.rs b/src/api.rs
new file mode 100644
index 0000000..2e44d66
--- /dev/null
+++ b/src/api.rs
@@ -0,0 +1,1545 @@
+use crate::externs::{free, malloc, memcpy, memmove, memset, realloc, strdup, strlen};
+use crate::success::{Success, FAIL, OK};
+use crate::yaml::{size_t, yaml_char_t};
+use crate::{
+ libc, yaml_break_t, yaml_document_t, yaml_emitter_state_t, yaml_emitter_t, yaml_encoding_t,
+ yaml_event_t, yaml_mapping_style_t, yaml_mark_t, yaml_node_item_t, yaml_node_pair_t,
+ yaml_node_t, yaml_parser_state_t, yaml_parser_t, yaml_read_handler_t, yaml_scalar_style_t,
+ yaml_sequence_style_t, yaml_simple_key_t, yaml_tag_directive_t, yaml_token_t,
+ yaml_version_directive_t, yaml_write_handler_t, PointerExt, YAML_ALIAS_EVENT, YAML_ALIAS_TOKEN,
+ YAML_ANCHOR_TOKEN, YAML_ANY_ENCODING, YAML_DOCUMENT_END_EVENT, YAML_DOCUMENT_START_EVENT,
+ YAML_MAPPING_END_EVENT, YAML_MAPPING_NODE, YAML_MAPPING_START_EVENT, YAML_SCALAR_EVENT,
+ YAML_SCALAR_NODE, YAML_SCALAR_TOKEN, YAML_SEQUENCE_END_EVENT, YAML_SEQUENCE_NODE,
+ YAML_SEQUENCE_START_EVENT, YAML_STREAM_END_EVENT, YAML_STREAM_START_EVENT,
+ YAML_TAG_DIRECTIVE_TOKEN, YAML_TAG_TOKEN,
+};
+use core::mem::{size_of, MaybeUninit};
+use core::ptr::{self, addr_of_mut};
+
+const INPUT_RAW_BUFFER_SIZE: usize = 16384;
+const INPUT_BUFFER_SIZE: usize = INPUT_RAW_BUFFER_SIZE * 3;
+const OUTPUT_BUFFER_SIZE: usize = 16384;
+const OUTPUT_RAW_BUFFER_SIZE: usize = OUTPUT_BUFFER_SIZE * 2 + 2;
+
+pub(crate) unsafe fn yaml_malloc(size: size_t) -> *mut libc::c_void {
+ malloc(size)
+}
+
+pub(crate) unsafe fn yaml_realloc(ptr: *mut libc::c_void, size: size_t) -> *mut libc::c_void {
+ if !ptr.is_null() {
+ realloc(ptr, size)
+ } else {
+ malloc(size)
+ }
+}
+
+pub(crate) unsafe fn yaml_free(ptr: *mut libc::c_void) {
+ if !ptr.is_null() {
+ free(ptr);
+ }
+}
+
+pub(crate) unsafe fn yaml_strdup(str: *const yaml_char_t) -> *mut yaml_char_t {
+ if str.is_null() {
+ return ptr::null_mut::<yaml_char_t>();
+ }
+ strdup(str as *mut libc::c_char) as *mut yaml_char_t
+}
+
+pub(crate) unsafe fn yaml_string_extend(
+ start: *mut *mut yaml_char_t,
+ pointer: *mut *mut yaml_char_t,
+ end: *mut *mut yaml_char_t,
+) {
+ let new_start: *mut yaml_char_t = yaml_realloc(
+ *start as *mut libc::c_void,
+ ((*end).c_offset_from(*start) as libc::c_long * 2_i64) as size_t,
+ ) as *mut yaml_char_t;
+ memset(
+ new_start.wrapping_offset((*end).c_offset_from(*start) as libc::c_long as isize)
+ as *mut libc::c_void,
+ 0,
+ (*end).c_offset_from(*start) as libc::c_long as libc::c_ulong,
+ );
+ *pointer = new_start.wrapping_offset((*pointer).c_offset_from(*start) as libc::c_long as isize);
+ *end =
+ new_start.wrapping_offset(((*end).c_offset_from(*start) as libc::c_long * 2_i64) as isize);
+ *start = new_start;
+}
+
+pub(crate) unsafe fn yaml_string_join(
+ a_start: *mut *mut yaml_char_t,
+ a_pointer: *mut *mut yaml_char_t,
+ a_end: *mut *mut yaml_char_t,
+ b_start: *mut *mut yaml_char_t,
+ b_pointer: *mut *mut yaml_char_t,
+ _b_end: *mut *mut yaml_char_t,
+) {
+ if *b_start == *b_pointer {
+ return;
+ }
+ while (*a_end).c_offset_from(*a_pointer) as libc::c_long
+ <= (*b_pointer).c_offset_from(*b_start) as libc::c_long
+ {
+ yaml_string_extend(a_start, a_pointer, a_end);
+ }
+ memcpy(
+ *a_pointer as *mut libc::c_void,
+ *b_start as *const libc::c_void,
+ (*b_pointer).c_offset_from(*b_start) as libc::c_long as libc::c_ulong,
+ );
+ *a_pointer =
+ (*a_pointer).wrapping_offset((*b_pointer).c_offset_from(*b_start) as libc::c_long as isize);
+}
+
+pub(crate) unsafe fn yaml_stack_extend(
+ start: *mut *mut libc::c_void,
+ top: *mut *mut libc::c_void,
+ end: *mut *mut libc::c_void,
+) {
+ let new_start: *mut libc::c_void = yaml_realloc(
+ *start,
+ ((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
+ * 2_i64) as size_t,
+ );
+ *top = (new_start as *mut libc::c_char).wrapping_offset(
+ (*top as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
+ as isize,
+ ) as *mut libc::c_void;
+ *end = (new_start as *mut libc::c_char).wrapping_offset(
+ ((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
+ * 2_i64) as isize,
+ ) as *mut libc::c_void;
+ *start = new_start;
+}
+
+pub(crate) unsafe fn yaml_queue_extend(
+ start: *mut *mut libc::c_void,
+ head: *mut *mut libc::c_void,
+ tail: *mut *mut libc::c_void,
+ end: *mut *mut libc::c_void,
+) {
+ if *start == *head && *tail == *end {
+ let new_start: *mut libc::c_void = yaml_realloc(
+ *start,
+ ((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
+ * 2_i64) as size_t,
+ );
+ *head = (new_start as *mut libc::c_char).wrapping_offset(
+ (*head as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
+ as isize,
+ ) as *mut libc::c_void;
+ *tail = (new_start as *mut libc::c_char).wrapping_offset(
+ (*tail as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
+ as isize,
+ ) as *mut libc::c_void;
+ *end = (new_start as *mut libc::c_char).wrapping_offset(
+ ((*end as *mut libc::c_char).c_offset_from(*start as *mut libc::c_char) as libc::c_long
+ * 2_i64) as isize,
+ ) as *mut libc::c_void;
+ *start = new_start;
+ }
+ if *tail == *end {
+ if *head != *tail {
+ memmove(
+ *start,
+ *head,
+ (*tail as *mut libc::c_char).c_offset_from(*head as *mut libc::c_char)
+ as libc::c_long as libc::c_ulong,
+ );
+ }
+ *tail = (*start as *mut libc::c_char).wrapping_offset(
+ (*tail as *mut libc::c_char).c_offset_from(*head as *mut libc::c_char) as libc::c_long
+ as isize,
+ ) as *mut libc::c_void;
+ *head = *start;
+ }
+}
+
+/// Initialize a parser.
+///
+/// This function creates a new parser object. An application is responsible
+/// for destroying the object using the yaml_parser_delete() function.
+pub unsafe fn yaml_parser_initialize(parser: *mut yaml_parser_t) -> Success {
+ __assert!(!parser.is_null());
+ memset(
+ parser as *mut libc::c_void,
+ 0,
+ size_of::<yaml_parser_t>() as libc::c_ulong,
+ );
+ BUFFER_INIT!((*parser).raw_buffer, INPUT_RAW_BUFFER_SIZE);
+ BUFFER_INIT!((*parser).buffer, INPUT_BUFFER_SIZE);
+ QUEUE_INIT!((*parser).tokens, yaml_token_t);
+ STACK_INIT!((*parser).indents, libc::c_int);
+ STACK_INIT!((*parser).simple_keys, yaml_simple_key_t);
+ STACK_INIT!((*parser).states, yaml_parser_state_t);
+ STACK_INIT!((*parser).marks, yaml_mark_t);
+ STACK_INIT!((*parser).tag_directives, yaml_tag_directive_t);
+ OK
+}
+
+/// Destroy a parser.
+pub unsafe fn yaml_parser_delete(parser: *mut yaml_parser_t) {
+ __assert!(!parser.is_null());
+ BUFFER_DEL!((*parser).raw_buffer);
+ BUFFER_DEL!((*parser).buffer);
+ while !QUEUE_EMPTY!((*parser).tokens) {
+ yaml_token_delete(addr_of_mut!(DEQUEUE!((*parser).tokens)));
+ }
+ QUEUE_DEL!((*parser).tokens);
+ STACK_DEL!((*parser).indents);
+ STACK_DEL!((*parser).simple_keys);
+ STACK_DEL!((*parser).states);
+ STACK_DEL!((*parser).marks);
+ while !STACK_EMPTY!((*parser).tag_directives) {
+ let tag_directive = POP!((*parser).tag_directives);
+ yaml_free(tag_directive.handle as *mut libc::c_void);
+ yaml_free(tag_directive.prefix as *mut libc::c_void);
+ }
+ STACK_DEL!((*parser).tag_directives);
+ memset(
+ parser as *mut libc::c_void,
+ 0,
+ size_of::<yaml_parser_t>() as libc::c_ulong,
+ );
+}
+
+unsafe fn yaml_string_read_handler(
+ data: *mut libc::c_void,
+ buffer: *mut libc::c_uchar,
+ mut size: size_t,
+ size_read: *mut size_t,
+) -> libc::c_int {
+ let parser: *mut yaml_parser_t = data as *mut yaml_parser_t;
+ if (*parser).input.string.current == (*parser).input.string.end {
+ *size_read = 0_u64;
+ return 1;
+ }
+ if size
+ > (*parser)
+ .input
+ .string
+ .end
+ .c_offset_from((*parser).input.string.current) as libc::c_long as size_t
+ {
+ size = (*parser)
+ .input
+ .string
+ .end
+ .c_offset_from((*parser).input.string.current) as libc::c_long as size_t;
+ }
+ memcpy(
+ buffer as *mut libc::c_void,
+ (*parser).input.string.current as *const libc::c_void,
+ size,
+ );
+ let fresh80 = addr_of_mut!((*parser).input.string.current);
+ *fresh80 = (*fresh80).wrapping_offset(size as isize);
+ *size_read = size;
+ 1
+}
+
+/// Set a string input.
+///
+/// Note that the `input` pointer must be valid while the `parser` object
+/// exists. The application is responsible for destroying `input` after
+/// destroying the `parser`.
+pub unsafe fn yaml_parser_set_input_string(
+ parser: *mut yaml_parser_t,
+ input: *const libc::c_uchar,
+ size: size_t,
+) {
+ __assert!(!parser.is_null());
+ __assert!(((*parser).read_handler).is_none());
+ __assert!(!input.is_null());
+ let fresh81 = addr_of_mut!((*parser).read_handler);
+ *fresh81 = Some(
+ yaml_string_read_handler
+ as unsafe fn(*mut libc::c_void, *mut libc::c_uchar, size_t, *mut size_t) -> libc::c_int,
+ );
+ let fresh82 = addr_of_mut!((*parser).read_handler_data);
+ *fresh82 = parser as *mut libc::c_void;
+ let fresh83 = addr_of_mut!((*parser).input.string.start);
+ *fresh83 = input;
+ let fresh84 = addr_of_mut!((*parser).input.string.current);
+ *fresh84 = input;
+ let fresh85 = addr_of_mut!((*parser).input.string.end);
+ *fresh85 = input.wrapping_offset(size as isize);
+}
+
+/// Set a generic input handler.
+pub unsafe fn yaml_parser_set_input(
+ parser: *mut yaml_parser_t,
+ handler: yaml_read_handler_t,
+ data: *mut libc::c_void,
+) {
+ __assert!(!parser.is_null());
+ __assert!(((*parser).read_handler).is_none());
+ let fresh89 = addr_of_mut!((*parser).read_handler);
+ *fresh89 = Some(handler);
+ let fresh90 = addr_of_mut!((*parser).read_handler_data);
+ *fresh90 = data;
+}
+
+/// Set the source encoding.
+pub unsafe fn yaml_parser_set_encoding(parser: *mut yaml_parser_t, encoding: yaml_encoding_t) {
+ __assert!(!parser.is_null());
+ __assert!((*parser).encoding == YAML_ANY_ENCODING);
+ (*parser).encoding = encoding;
+}
+
+/// Initialize an emitter.
+///
+/// This function creates a new emitter object. An application is responsible
+/// for destroying the object using the yaml_emitter_delete() function.
+pub unsafe fn yaml_emitter_initialize(emitter: *mut yaml_emitter_t) -> Success {
+ __assert!(!emitter.is_null());
+ memset(
+ emitter as *mut libc::c_void,
+ 0,
+ size_of::<yaml_emitter_t>() as libc::c_ulong,
+ );
+ BUFFER_INIT!((*emitter).buffer, OUTPUT_BUFFER_SIZE);
+ BUFFER_INIT!((*emitter).raw_buffer, OUTPUT_RAW_BUFFER_SIZE);
+ STACK_INIT!((*emitter).states, yaml_emitter_state_t);
+ QUEUE_INIT!((*emitter).events, yaml_event_t);
+ STACK_INIT!((*emitter).indents, libc::c_int);
+ STACK_INIT!((*emitter).tag_directives, yaml_tag_directive_t);
+ OK
+}
+
+/// Destroy an emitter.
+pub unsafe fn yaml_emitter_delete(emitter: *mut yaml_emitter_t) {
+ __assert!(!emitter.is_null());
+ BUFFER_DEL!((*emitter).buffer);
+ BUFFER_DEL!((*emitter).raw_buffer);
+ STACK_DEL!((*emitter).states);
+ while !QUEUE_EMPTY!((*emitter).events) {
+ yaml_event_delete(addr_of_mut!(DEQUEUE!((*emitter).events)));
+ }
+ QUEUE_DEL!((*emitter).events);
+ STACK_DEL!((*emitter).indents);
+ while !STACK_EMPTY!((*emitter).tag_directives) {
+ let tag_directive = POP!((*emitter).tag_directives);
+ yaml_free(tag_directive.handle as *mut libc::c_void);
+ yaml_free(tag_directive.prefix as *mut libc::c_void);
+ }
+ STACK_DEL!((*emitter).tag_directives);
+ yaml_free((*emitter).anchors as *mut libc::c_void);
+ memset(
+ emitter as *mut libc::c_void,
+ 0,
+ size_of::<yaml_emitter_t>() as libc::c_ulong,
+ );
+}
+
+unsafe fn yaml_string_write_handler(
+ data: *mut libc::c_void,
+ buffer: *mut libc::c_uchar,
+ size: size_t,
+) -> libc::c_int {
+ let emitter: *mut yaml_emitter_t = data as *mut yaml_emitter_t;
+ if (*emitter)
+ .output
+ .string
+ .size
+ .wrapping_sub(*(*emitter).output.string.size_written)
+ < size
+ {
+ memcpy(
+ (*emitter)
+ .output
+ .string
+ .buffer
+ .wrapping_offset(*(*emitter).output.string.size_written as isize)
+ as *mut libc::c_void,
+ buffer as *const libc::c_void,
+ (*emitter)
+ .output
+ .string
+ .size
+ .wrapping_sub(*(*emitter).output.string.size_written),
+ );
+ *(*emitter).output.string.size_written = (*emitter).output.string.size;
+ return 0;
+ }
+ memcpy(
+ (*emitter)
+ .output
+ .string
+ .buffer
+ .wrapping_offset(*(*emitter).output.string.size_written as isize)
+ as *mut libc::c_void,
+ buffer as *const libc::c_void,
+ size,
+ );
+ let fresh153 = addr_of_mut!((*(*emitter).output.string.size_written));
+ *fresh153 = (*fresh153 as libc::c_ulong).wrapping_add(size) as size_t as size_t;
+ 1
+}
+
+/// Set a string output.
+///
+/// The emitter will write the output characters to the `output` buffer of the
+/// size `size`. The emitter will set `size_written` to the number of written
+/// bytes. If the buffer is smaller than required, the emitter produces the
+/// YAML_WRITE_ERROR error.
+pub unsafe fn yaml_emitter_set_output_string(
+ emitter: *mut yaml_emitter_t,
+ output: *mut libc::c_uchar,
+ size: size_t,
+ size_written: *mut size_t,
+) {
+ __assert!(!emitter.is_null());
+ __assert!(((*emitter).write_handler).is_none());
+ __assert!(!output.is_null());
+ let fresh154 = addr_of_mut!((*emitter).write_handler);
+ *fresh154 = Some(
+ yaml_string_write_handler
+ as unsafe fn(*mut libc::c_void, *mut libc::c_uchar, size_t) -> libc::c_int,
+ );
+ let fresh155 = addr_of_mut!((*emitter).write_handler_data);
+ *fresh155 = emitter as *mut libc::c_void;
+ let fresh156 = addr_of_mut!((*emitter).output.string.buffer);
+ *fresh156 = output;
+ (*emitter).output.string.size = size;
+ let fresh157 = addr_of_mut!((*emitter).output.string.size_written);
+ *fresh157 = size_written;
+ *size_written = 0_u64;
+}
+
+/// Set a generic output handler.
+pub unsafe fn yaml_emitter_set_output(
+ emitter: *mut yaml_emitter_t,
+ handler: yaml_write_handler_t,
+ data: *mut libc::c_void,
+) {
+ __assert!(!emitter.is_null());
+ __assert!(((*emitter).write_handler).is_none());
+ let fresh161 = addr_of_mut!((*emitter).write_handler);
+ *fresh161 = Some(handler);
+ let fresh162 = addr_of_mut!((*emitter).write_handler_data);
+ *fresh162 = data;
+}
+
+/// Set the output encoding.
+pub unsafe fn yaml_emitter_set_encoding(emitter: *mut yaml_emitter_t, encoding: yaml_encoding_t) {
+ __assert!(!emitter.is_null());
+ __assert!((*emitter).encoding == YAML_ANY_ENCODING);
+ (*emitter).encoding = encoding;
+}
+
+/// Set if the output should be in the "canonical" format as in the YAML
+/// specification.
+pub unsafe fn yaml_emitter_set_canonical(emitter: *mut yaml_emitter_t, canonical: bool) {
+ __assert!(!emitter.is_null());
+ (*emitter).canonical = canonical;
+}
+
+/// Set the indentation increment.
+pub unsafe fn yaml_emitter_set_indent(emitter: *mut yaml_emitter_t, indent: libc::c_int) {
+ __assert!(!emitter.is_null());
+ (*emitter).best_indent = if 1 < indent && indent < 10 { indent } else { 2 };
+}
+
+/// Set the preferred line width. -1 means unlimited.
+pub unsafe fn yaml_emitter_set_width(emitter: *mut yaml_emitter_t, width: libc::c_int) {
+ __assert!(!emitter.is_null());
+ (*emitter).best_width = if width >= 0 { width } else { -1 };
+}
+
+/// Set if unescaped non-ASCII characters are allowed.
+pub unsafe fn yaml_emitter_set_unicode(emitter: *mut yaml_emitter_t, unicode: bool) {
+ __assert!(!emitter.is_null());
+ (*emitter).unicode = unicode;
+}
+
+/// Set the preferred line break.
+pub unsafe fn yaml_emitter_set_break(emitter: *mut yaml_emitter_t, line_break: yaml_break_t) {
+ __assert!(!emitter.is_null());
+ (*emitter).line_break = line_break;
+}
+
+/// Free any memory allocated for a token object.
+pub unsafe fn yaml_token_delete(token: *mut yaml_token_t) {
+ __assert!(!token.is_null());
+ match (*token).type_ {
+ YAML_TAG_DIRECTIVE_TOKEN => {
+ yaml_free((*token).data.tag_directive.handle as *mut libc::c_void);
+ yaml_free((*token).data.tag_directive.prefix as *mut libc::c_void);
+ }
+ YAML_ALIAS_TOKEN => {
+ yaml_free((*token).data.alias.value as *mut libc::c_void);
+ }
+ YAML_ANCHOR_TOKEN => {
+ yaml_free((*token).data.anchor.value as *mut libc::c_void);
+ }
+ YAML_TAG_TOKEN => {
+ yaml_free((*token).data.tag.handle as *mut libc::c_void);
+ yaml_free((*token).data.tag.suffix as *mut libc::c_void);
+ }
+ YAML_SCALAR_TOKEN => {
+ yaml_free((*token).data.scalar.value as *mut libc::c_void);
+ }
+ _ => {}
+ }
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+}
+
+unsafe fn yaml_check_utf8(start: *const yaml_char_t, length: size_t) -> Success {
+ let end: *const yaml_char_t = start.wrapping_offset(length as isize);
+ let mut pointer: *const yaml_char_t = start;
+ while pointer < end {
+ let mut octet: libc::c_uchar;
+ let mut value: libc::c_uint;
+ let mut k: size_t;
+ octet = *pointer;
+ let width: libc::c_uint = if octet & 0x80 == 0 {
+ 1
+ } else if octet & 0xE0 == 0xC0 {
+ 2
+ } else if octet & 0xF0 == 0xE0 {
+ 3
+ } else if octet & 0xF8 == 0xF0 {
+ 4
+ } else {
+ 0
+ } as libc::c_uint;
+ value = if octet & 0x80 == 0 {
+ octet & 0x7F
+ } else if octet & 0xE0 == 0xC0 {
+ octet & 0x1F
+ } else if octet & 0xF0 == 0xE0 {
+ octet & 0xF
+ } else if octet & 0xF8 == 0xF0 {
+ octet & 0x7
+ } else {
+ 0
+ } as libc::c_uint;
+ if width == 0 {
+ return FAIL;
+ }
+ if pointer.wrapping_offset(width as isize) > end {
+ return FAIL;
+ }
+ k = 1_u64;
+ while k < width as libc::c_ulong {
+ octet = *pointer.wrapping_offset(k as isize);
+ if octet & 0xC0 != 0x80 {
+ return FAIL;
+ }
+ value = (value << 6).wrapping_add((octet & 0x3F) as libc::c_uint);
+ k = k.wrapping_add(1);
+ }
+ if !(width == 1
+ || width == 2 && value >= 0x80
+ || width == 3 && value >= 0x800
+ || width == 4 && value >= 0x10000)
+ {
+ return FAIL;
+ }
+ pointer = pointer.wrapping_offset(width as isize);
+ }
+ OK
+}
+
+/// Create the STREAM-START event.
+pub unsafe fn yaml_stream_start_event_initialize(
+ event: *mut yaml_event_t,
+ encoding: yaml_encoding_t,
+) -> Success {
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ __assert!(!event.is_null());
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_STREAM_START_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ (*event).data.stream_start.encoding = encoding;
+ OK
+}
+
+/// Create the STREAM-END event.
+pub unsafe fn yaml_stream_end_event_initialize(event: *mut yaml_event_t) -> Success {
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ __assert!(!event.is_null());
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_STREAM_END_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ OK
+}
+
+/// Create the DOCUMENT-START event.
+///
+/// The `implicit` argument is considered as a stylistic parameter and may be
+/// ignored by the emitter.
+pub unsafe fn yaml_document_start_event_initialize(
+ event: *mut yaml_event_t,
+ version_directive: *mut yaml_version_directive_t,
+ tag_directives_start: *mut yaml_tag_directive_t,
+ tag_directives_end: *mut yaml_tag_directive_t,
+ implicit: bool,
+) -> Success {
+ let current_block: u64;
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ let mut version_directive_copy: *mut yaml_version_directive_t =
+ ptr::null_mut::<yaml_version_directive_t>();
+ struct TagDirectivesCopy {
+ start: *mut yaml_tag_directive_t,
+ end: *mut yaml_tag_directive_t,
+ top: *mut yaml_tag_directive_t,
+ }
+ let mut tag_directives_copy = TagDirectivesCopy {
+ start: ptr::null_mut::<yaml_tag_directive_t>(),
+ end: ptr::null_mut::<yaml_tag_directive_t>(),
+ top: ptr::null_mut::<yaml_tag_directive_t>(),
+ };
+ let mut value = yaml_tag_directive_t {
+ handle: ptr::null_mut::<yaml_char_t>(),
+ prefix: ptr::null_mut::<yaml_char_t>(),
+ };
+ __assert!(!event.is_null());
+ __assert!(
+ !tag_directives_start.is_null() && !tag_directives_end.is_null()
+ || tag_directives_start == tag_directives_end
+ );
+ if !version_directive.is_null() {
+ version_directive_copy = yaml_malloc(size_of::<yaml_version_directive_t>() as libc::c_ulong)
+ as *mut yaml_version_directive_t;
+ (*version_directive_copy).major = (*version_directive).major;
+ (*version_directive_copy).minor = (*version_directive).minor;
+ }
+ if tag_directives_start != tag_directives_end {
+ let mut tag_directive: *mut yaml_tag_directive_t;
+ STACK_INIT!(tag_directives_copy, yaml_tag_directive_t);
+ tag_directive = tag_directives_start;
+ loop {
+ if !(tag_directive != tag_directives_end) {
+ current_block = 16203760046146113240;
+ break;
+ }
+ __assert!(!((*tag_directive).handle).is_null());
+ __assert!(!((*tag_directive).prefix).is_null());
+ if yaml_check_utf8(
+ (*tag_directive).handle,
+ strlen((*tag_directive).handle as *mut libc::c_char),
+ )
+ .fail
+ {
+ current_block = 14964981520188694172;
+ break;
+ }
+ if yaml_check_utf8(
+ (*tag_directive).prefix,
+ strlen((*tag_directive).prefix as *mut libc::c_char),
+ )
+ .fail
+ {
+ current_block = 14964981520188694172;
+ break;
+ }
+ value.handle = yaml_strdup((*tag_directive).handle);
+ value.prefix = yaml_strdup((*tag_directive).prefix);
+ if value.handle.is_null() || value.prefix.is_null() {
+ current_block = 14964981520188694172;
+ break;
+ }
+ PUSH!(tag_directives_copy, value);
+ value.handle = ptr::null_mut::<yaml_char_t>();
+ value.prefix = ptr::null_mut::<yaml_char_t>();
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ } else {
+ current_block = 16203760046146113240;
+ }
+ if current_block != 14964981520188694172 {
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_DOCUMENT_START_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ let fresh164 = addr_of_mut!((*event).data.document_start.version_directive);
+ *fresh164 = version_directive_copy;
+ let fresh165 = addr_of_mut!((*event).data.document_start.tag_directives.start);
+ *fresh165 = tag_directives_copy.start;
+ let fresh166 = addr_of_mut!((*event).data.document_start.tag_directives.end);
+ *fresh166 = tag_directives_copy.top;
+ (*event).data.document_start.implicit = implicit;
+ return OK;
+ }
+ yaml_free(version_directive_copy as *mut libc::c_void);
+ while !STACK_EMPTY!(tag_directives_copy) {
+ let value = POP!(tag_directives_copy);
+ yaml_free(value.handle as *mut libc::c_void);
+ yaml_free(value.prefix as *mut libc::c_void);
+ }
+ STACK_DEL!(tag_directives_copy);
+ yaml_free(value.handle as *mut libc::c_void);
+ yaml_free(value.prefix as *mut libc::c_void);
+ FAIL
+}
+
+/// Create the DOCUMENT-END event.
+///
+/// The `implicit` argument is considered as a stylistic parameter and may be
+/// ignored by the emitter.
+pub unsafe fn yaml_document_end_event_initialize(
+ event: *mut yaml_event_t,
+ implicit: bool,
+) -> Success {
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ __assert!(!event.is_null());
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_DOCUMENT_END_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ (*event).data.document_end.implicit = implicit;
+ OK
+}
+
+/// Create an ALIAS event.
+pub unsafe fn yaml_alias_event_initialize(
+ event: *mut yaml_event_t,
+ anchor: *const yaml_char_t,
+) -> Success {
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ __assert!(!event.is_null());
+ __assert!(!anchor.is_null());
+ if yaml_check_utf8(anchor, strlen(anchor as *mut libc::c_char)).fail {
+ return FAIL;
+ }
+ let anchor_copy: *mut yaml_char_t = yaml_strdup(anchor);
+ if anchor_copy.is_null() {
+ return FAIL;
+ }
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_ALIAS_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ let fresh167 = addr_of_mut!((*event).data.alias.anchor);
+ *fresh167 = anchor_copy;
+ OK
+}
+
+/// Create a SCALAR event.
+///
+/// The `style` argument may be ignored by the emitter.
+///
+/// Either the `tag` attribute or one of the `plain_implicit` and
+/// `quoted_implicit` flags must be set.
+///
+pub unsafe fn yaml_scalar_event_initialize(
+ event: *mut yaml_event_t,
+ anchor: *const yaml_char_t,
+ tag: *const yaml_char_t,
+ value: *const yaml_char_t,
+ mut length: libc::c_int,
+ plain_implicit: bool,
+ quoted_implicit: bool,
+ style: yaml_scalar_style_t,
+) -> Success {
+ let mut current_block: u64;
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ let mut anchor_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut value_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ __assert!(!event.is_null());
+ __assert!(!value.is_null());
+ if !anchor.is_null() {
+ if yaml_check_utf8(anchor, strlen(anchor as *mut libc::c_char)).fail {
+ current_block = 16285396129609901221;
+ } else {
+ anchor_copy = yaml_strdup(anchor);
+ if anchor_copy.is_null() {
+ current_block = 16285396129609901221;
+ } else {
+ current_block = 8515828400728868193;
+ }
+ }
+ } else {
+ current_block = 8515828400728868193;
+ }
+ if current_block == 8515828400728868193 {
+ if !tag.is_null() {
+ if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).fail {
+ current_block = 16285396129609901221;
+ } else {
+ tag_copy = yaml_strdup(tag);
+ if tag_copy.is_null() {
+ current_block = 16285396129609901221;
+ } else {
+ current_block = 12800627514080957624;
+ }
+ }
+ } else {
+ current_block = 12800627514080957624;
+ }
+ if current_block != 16285396129609901221 {
+ if length < 0 {
+ length = strlen(value as *mut libc::c_char) as libc::c_int;
+ }
+ if yaml_check_utf8(value, length as size_t).ok {
+ value_copy = yaml_malloc((length + 1) as size_t) as *mut yaml_char_t;
+ memcpy(
+ value_copy as *mut libc::c_void,
+ value as *const libc::c_void,
+ length as libc::c_ulong,
+ );
+ *value_copy.wrapping_offset(length as isize) = b'\0';
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SCALAR_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ let fresh168 = addr_of_mut!((*event).data.scalar.anchor);
+ *fresh168 = anchor_copy;
+ let fresh169 = addr_of_mut!((*event).data.scalar.tag);
+ *fresh169 = tag_copy;
+ let fresh170 = addr_of_mut!((*event).data.scalar.value);
+ *fresh170 = value_copy;
+ (*event).data.scalar.length = length as size_t;
+ (*event).data.scalar.plain_implicit = plain_implicit;
+ (*event).data.scalar.quoted_implicit = quoted_implicit;
+ (*event).data.scalar.style = style;
+ return OK;
+ }
+ }
+ }
+ yaml_free(anchor_copy as *mut libc::c_void);
+ yaml_free(tag_copy as *mut libc::c_void);
+ yaml_free(value_copy as *mut libc::c_void);
+ FAIL
+}
+
+/// Create a SEQUENCE-START event.
+///
+/// The `style` argument may be ignored by the emitter.
+///
+/// Either the `tag` attribute or the `implicit` flag must be set.
+pub unsafe fn yaml_sequence_start_event_initialize(
+ event: *mut yaml_event_t,
+ anchor: *const yaml_char_t,
+ tag: *const yaml_char_t,
+ implicit: bool,
+ style: yaml_sequence_style_t,
+) -> Success {
+ let mut current_block: u64;
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ let mut anchor_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ __assert!(!event.is_null());
+ if !anchor.is_null() {
+ if yaml_check_utf8(anchor, strlen(anchor as *mut libc::c_char)).fail {
+ current_block = 8817775685815971442;
+ } else {
+ anchor_copy = yaml_strdup(anchor);
+ if anchor_copy.is_null() {
+ current_block = 8817775685815971442;
+ } else {
+ current_block = 11006700562992250127;
+ }
+ }
+ } else {
+ current_block = 11006700562992250127;
+ }
+ match current_block {
+ 11006700562992250127 => {
+ if !tag.is_null() {
+ if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).fail {
+ current_block = 8817775685815971442;
+ } else {
+ tag_copy = yaml_strdup(tag);
+ if tag_copy.is_null() {
+ current_block = 8817775685815971442;
+ } else {
+ current_block = 7651349459974463963;
+ }
+ }
+ } else {
+ current_block = 7651349459974463963;
+ }
+ if current_block != 8817775685815971442 {
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SEQUENCE_START_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ let fresh171 = addr_of_mut!((*event).data.sequence_start.anchor);
+ *fresh171 = anchor_copy;
+ let fresh172 = addr_of_mut!((*event).data.sequence_start.tag);
+ *fresh172 = tag_copy;
+ (*event).data.sequence_start.implicit = implicit;
+ (*event).data.sequence_start.style = style;
+ return OK;
+ }
+ }
+ _ => {}
+ }
+ yaml_free(anchor_copy as *mut libc::c_void);
+ yaml_free(tag_copy as *mut libc::c_void);
+ FAIL
+}
+
+/// Create a SEQUENCE-END event.
+pub unsafe fn yaml_sequence_end_event_initialize(event: *mut yaml_event_t) -> Success {
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ __assert!(!event.is_null());
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SEQUENCE_END_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ OK
+}
+
+/// Create a MAPPING-START event.
+///
+/// The `style` argument may be ignored by the emitter.
+///
+/// Either the `tag` attribute or the `implicit` flag must be set.
+pub unsafe fn yaml_mapping_start_event_initialize(
+ event: *mut yaml_event_t,
+ anchor: *const yaml_char_t,
+ tag: *const yaml_char_t,
+ implicit: bool,
+ style: yaml_mapping_style_t,
+) -> Success {
+ let mut current_block: u64;
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ let mut anchor_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ __assert!(!event.is_null());
+ if !anchor.is_null() {
+ if yaml_check_utf8(anchor, strlen(anchor as *mut libc::c_char)).fail {
+ current_block = 14748279734549812740;
+ } else {
+ anchor_copy = yaml_strdup(anchor);
+ if anchor_copy.is_null() {
+ current_block = 14748279734549812740;
+ } else {
+ current_block = 11006700562992250127;
+ }
+ }
+ } else {
+ current_block = 11006700562992250127;
+ }
+ if current_block == 11006700562992250127 {
+ if !tag.is_null() {
+ if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).fail {
+ current_block = 14748279734549812740;
+ } else {
+ tag_copy = yaml_strdup(tag);
+ if tag_copy.is_null() {
+ current_block = 14748279734549812740;
+ } else {
+ current_block = 7651349459974463963;
+ }
+ }
+ } else {
+ current_block = 7651349459974463963;
+ }
+ if current_block != 14748279734549812740 {
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_MAPPING_START_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ let fresh173 = addr_of_mut!((*event).data.mapping_start.anchor);
+ *fresh173 = anchor_copy;
+ let fresh174 = addr_of_mut!((*event).data.mapping_start.tag);
+ *fresh174 = tag_copy;
+ (*event).data.mapping_start.implicit = implicit;
+ (*event).data.mapping_start.style = style;
+ return OK;
+ }
+ }
+ yaml_free(anchor_copy as *mut libc::c_void);
+ yaml_free(tag_copy as *mut libc::c_void);
+ FAIL
+}
+
+/// Create a MAPPING-END event.
+pub unsafe fn yaml_mapping_end_event_initialize(event: *mut yaml_event_t) -> Success {
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ __assert!(!event.is_null());
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_MAPPING_END_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ OK
+}
+
+/// Free any memory allocated for an event object.
+pub unsafe fn yaml_event_delete(event: *mut yaml_event_t) {
+ let mut tag_directive: *mut yaml_tag_directive_t;
+ __assert!(!event.is_null());
+ match (*event).type_ {
+ YAML_DOCUMENT_START_EVENT => {
+ yaml_free((*event).data.document_start.version_directive as *mut libc::c_void);
+ tag_directive = (*event).data.document_start.tag_directives.start;
+ while tag_directive != (*event).data.document_start.tag_directives.end {
+ yaml_free((*tag_directive).handle as *mut libc::c_void);
+ yaml_free((*tag_directive).prefix as *mut libc::c_void);
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ yaml_free((*event).data.document_start.tag_directives.start as *mut libc::c_void);
+ }
+ YAML_ALIAS_EVENT => {
+ yaml_free((*event).data.alias.anchor as *mut libc::c_void);
+ }
+ YAML_SCALAR_EVENT => {
+ yaml_free((*event).data.scalar.anchor as *mut libc::c_void);
+ yaml_free((*event).data.scalar.tag as *mut libc::c_void);
+ yaml_free((*event).data.scalar.value as *mut libc::c_void);
+ }
+ YAML_SEQUENCE_START_EVENT => {
+ yaml_free((*event).data.sequence_start.anchor as *mut libc::c_void);
+ yaml_free((*event).data.sequence_start.tag as *mut libc::c_void);
+ }
+ YAML_MAPPING_START_EVENT => {
+ yaml_free((*event).data.mapping_start.anchor as *mut libc::c_void);
+ yaml_free((*event).data.mapping_start.tag as *mut libc::c_void);
+ }
+ _ => {}
+ }
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+}
+
+/// Create a YAML document.
+pub unsafe fn yaml_document_initialize(
+ document: *mut yaml_document_t,
+ version_directive: *mut yaml_version_directive_t,
+ tag_directives_start: *mut yaml_tag_directive_t,
+ tag_directives_end: *mut yaml_tag_directive_t,
+ start_implicit: bool,
+ end_implicit: bool,
+) -> Success {
+ let current_block: u64;
+ struct Nodes {
+ start: *mut yaml_node_t,
+ end: *mut yaml_node_t,
+ top: *mut yaml_node_t,
+ }
+ let mut nodes = Nodes {
+ start: ptr::null_mut::<yaml_node_t>(),
+ end: ptr::null_mut::<yaml_node_t>(),
+ top: ptr::null_mut::<yaml_node_t>(),
+ };
+ let mut version_directive_copy: *mut yaml_version_directive_t =
+ ptr::null_mut::<yaml_version_directive_t>();
+ struct TagDirectivesCopy {
+ start: *mut yaml_tag_directive_t,
+ end: *mut yaml_tag_directive_t,
+ top: *mut yaml_tag_directive_t,
+ }
+ let mut tag_directives_copy = TagDirectivesCopy {
+ start: ptr::null_mut::<yaml_tag_directive_t>(),
+ end: ptr::null_mut::<yaml_tag_directive_t>(),
+ top: ptr::null_mut::<yaml_tag_directive_t>(),
+ };
+ let mut value = yaml_tag_directive_t {
+ handle: ptr::null_mut::<yaml_char_t>(),
+ prefix: ptr::null_mut::<yaml_char_t>(),
+ };
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ __assert!(!document.is_null());
+ __assert!(
+ !tag_directives_start.is_null() && !tag_directives_end.is_null()
+ || tag_directives_start == tag_directives_end
+ );
+ STACK_INIT!(nodes, yaml_node_t);
+ if !version_directive.is_null() {
+ version_directive_copy = yaml_malloc(size_of::<yaml_version_directive_t>() as libc::c_ulong)
+ as *mut yaml_version_directive_t;
+ (*version_directive_copy).major = (*version_directive).major;
+ (*version_directive_copy).minor = (*version_directive).minor;
+ }
+ if tag_directives_start != tag_directives_end {
+ let mut tag_directive: *mut yaml_tag_directive_t;
+ STACK_INIT!(tag_directives_copy, yaml_tag_directive_t);
+ tag_directive = tag_directives_start;
+ loop {
+ if !(tag_directive != tag_directives_end) {
+ current_block = 14818589718467733107;
+ break;
+ }
+ __assert!(!((*tag_directive).handle).is_null());
+ __assert!(!((*tag_directive).prefix).is_null());
+ if yaml_check_utf8(
+ (*tag_directive).handle,
+ strlen((*tag_directive).handle as *mut libc::c_char),
+ )
+ .fail
+ {
+ current_block = 8142820162064489797;
+ break;
+ }
+ if yaml_check_utf8(
+ (*tag_directive).prefix,
+ strlen((*tag_directive).prefix as *mut libc::c_char),
+ )
+ .fail
+ {
+ current_block = 8142820162064489797;
+ break;
+ }
+ value.handle = yaml_strdup((*tag_directive).handle);
+ value.prefix = yaml_strdup((*tag_directive).prefix);
+ if value.handle.is_null() || value.prefix.is_null() {
+ current_block = 8142820162064489797;
+ break;
+ }
+ PUSH!(tag_directives_copy, value);
+ value.handle = ptr::null_mut::<yaml_char_t>();
+ value.prefix = ptr::null_mut::<yaml_char_t>();
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ } else {
+ current_block = 14818589718467733107;
+ }
+ if current_block != 8142820162064489797 {
+ memset(
+ document as *mut libc::c_void,
+ 0,
+ size_of::<yaml_document_t>() as libc::c_ulong,
+ );
+ let fresh176 = addr_of_mut!((*document).nodes.start);
+ *fresh176 = nodes.start;
+ let fresh177 = addr_of_mut!((*document).nodes.end);
+ *fresh177 = nodes.end;
+ let fresh178 = addr_of_mut!((*document).nodes.top);
+ *fresh178 = nodes.start;
+ let fresh179 = addr_of_mut!((*document).version_directive);
+ *fresh179 = version_directive_copy;
+ let fresh180 = addr_of_mut!((*document).tag_directives.start);
+ *fresh180 = tag_directives_copy.start;
+ let fresh181 = addr_of_mut!((*document).tag_directives.end);
+ *fresh181 = tag_directives_copy.top;
+ (*document).start_implicit = start_implicit;
+ (*document).end_implicit = end_implicit;
+ (*document).start_mark = mark;
+ (*document).end_mark = mark;
+ return OK;
+ }
+ STACK_DEL!(nodes);
+ yaml_free(version_directive_copy as *mut libc::c_void);
+ while !STACK_EMPTY!(tag_directives_copy) {
+ let value = POP!(tag_directives_copy);
+ yaml_free(value.handle as *mut libc::c_void);
+ yaml_free(value.prefix as *mut libc::c_void);
+ }
+ STACK_DEL!(tag_directives_copy);
+ yaml_free(value.handle as *mut libc::c_void);
+ yaml_free(value.prefix as *mut libc::c_void);
+ FAIL
+}
+
+/// Delete a YAML document and all its nodes.
+pub unsafe fn yaml_document_delete(document: *mut yaml_document_t) {
+ let mut tag_directive: *mut yaml_tag_directive_t;
+ __assert!(!document.is_null());
+ while !STACK_EMPTY!((*document).nodes) {
+ let mut node = POP!((*document).nodes);
+ yaml_free(node.tag as *mut libc::c_void);
+ match node.type_ {
+ YAML_SCALAR_NODE => {
+ yaml_free(node.data.scalar.value as *mut libc::c_void);
+ }
+ YAML_SEQUENCE_NODE => {
+ STACK_DEL!(node.data.sequence.items);
+ }
+ YAML_MAPPING_NODE => {
+ STACK_DEL!(node.data.mapping.pairs);
+ }
+ _ => {
+ __assert!(false);
+ }
+ }
+ }
+ STACK_DEL!((*document).nodes);
+ yaml_free((*document).version_directive as *mut libc::c_void);
+ tag_directive = (*document).tag_directives.start;
+ while tag_directive != (*document).tag_directives.end {
+ yaml_free((*tag_directive).handle as *mut libc::c_void);
+ yaml_free((*tag_directive).prefix as *mut libc::c_void);
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ yaml_free((*document).tag_directives.start as *mut libc::c_void);
+ memset(
+ document as *mut libc::c_void,
+ 0,
+ size_of::<yaml_document_t>() as libc::c_ulong,
+ );
+}
+
+/// Get a node of a YAML document.
+///
+/// The pointer returned by this function is valid until any of the functions
+/// modifying the documents are called.
+///
+/// Returns the node objct or NULL if `node_id` is out of range.
+pub unsafe fn yaml_document_get_node(
+ document: *mut yaml_document_t,
+ index: libc::c_int,
+) -> *mut yaml_node_t {
+ __assert!(!document.is_null());
+ if index > 0 && (*document).nodes.start.wrapping_offset(index as isize) <= (*document).nodes.top
+ {
+ return (*document)
+ .nodes
+ .start
+ .wrapping_offset(index as isize)
+ .wrapping_offset(-1_isize);
+ }
+ ptr::null_mut::<yaml_node_t>()
+}
+
+/// Get the root of a YAML document node.
+///
+/// The root object is the first object added to the document.
+///
+/// The pointer returned by this function is valid until any of the functions
+/// modifying the documents are called.
+///
+/// An empty document produced by the parser signifies the end of a YAML stream.
+///
+/// Returns the node object or NULL if the document is empty.
+pub unsafe fn yaml_document_get_root_node(document: *mut yaml_document_t) -> *mut yaml_node_t {
+ __assert!(!document.is_null());
+ if (*document).nodes.top != (*document).nodes.start {
+ return (*document).nodes.start;
+ }
+ ptr::null_mut::<yaml_node_t>()
+}
+
+/// Create a SCALAR node and attach it to the document.
+///
+/// The `style` argument may be ignored by the emitter.
+///
+/// Returns the node id or 0 on error.
+#[must_use]
+pub unsafe fn yaml_document_add_scalar(
+ document: *mut yaml_document_t,
+ mut tag: *const yaml_char_t,
+ value: *const yaml_char_t,
+ mut length: libc::c_int,
+ style: yaml_scalar_style_t,
+) -> libc::c_int {
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut value_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut node = MaybeUninit::<yaml_node_t>::uninit();
+ let node = node.as_mut_ptr();
+ __assert!(!document.is_null());
+ __assert!(!value.is_null());
+ if tag.is_null() {
+ tag = b"tag:yaml.org,2002:str\0" as *const u8 as *const libc::c_char as *mut yaml_char_t;
+ }
+ if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).ok {
+ tag_copy = yaml_strdup(tag);
+ if !tag_copy.is_null() {
+ if length < 0 {
+ length = strlen(value as *mut libc::c_char) as libc::c_int;
+ }
+ if yaml_check_utf8(value, length as size_t).ok {
+ value_copy = yaml_malloc((length + 1) as size_t) as *mut yaml_char_t;
+ memcpy(
+ value_copy as *mut libc::c_void,
+ value as *const libc::c_void,
+ length as libc::c_ulong,
+ );
+ *value_copy.wrapping_offset(length as isize) = b'\0';
+ memset(
+ node as *mut libc::c_void,
+ 0,
+ size_of::<yaml_node_t>() as libc::c_ulong,
+ );
+ (*node).type_ = YAML_SCALAR_NODE;
+ (*node).tag = tag_copy;
+ (*node).start_mark = mark;
+ (*node).end_mark = mark;
+ (*node).data.scalar.value = value_copy;
+ (*node).data.scalar.length = length as size_t;
+ (*node).data.scalar.style = style;
+ PUSH!((*document).nodes, *node);
+ return (*document).nodes.top.c_offset_from((*document).nodes.start) as libc::c_int;
+ }
+ }
+ }
+ yaml_free(tag_copy as *mut libc::c_void);
+ yaml_free(value_copy as *mut libc::c_void);
+ 0
+}
+
+/// Create a SEQUENCE node and attach it to the document.
+///
+/// The `style` argument may be ignored by the emitter.
+///
+/// Returns the node id or 0 on error.
+#[must_use]
+pub unsafe fn yaml_document_add_sequence(
+ document: *mut yaml_document_t,
+ mut tag: *const yaml_char_t,
+ style: yaml_sequence_style_t,
+) -> libc::c_int {
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ struct Items {
+ start: *mut yaml_node_item_t,
+ end: *mut yaml_node_item_t,
+ top: *mut yaml_node_item_t,
+ }
+ let mut items = Items {
+ start: ptr::null_mut::<yaml_node_item_t>(),
+ end: ptr::null_mut::<yaml_node_item_t>(),
+ top: ptr::null_mut::<yaml_node_item_t>(),
+ };
+ let mut node = MaybeUninit::<yaml_node_t>::uninit();
+ let node = node.as_mut_ptr();
+ __assert!(!document.is_null());
+ if tag.is_null() {
+ tag = b"tag:yaml.org,2002:seq\0" as *const u8 as *const libc::c_char as *mut yaml_char_t;
+ }
+ if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).ok {
+ tag_copy = yaml_strdup(tag);
+ if !tag_copy.is_null() {
+ STACK_INIT!(items, yaml_node_item_t);
+ memset(
+ node as *mut libc::c_void,
+ 0,
+ size_of::<yaml_node_t>() as libc::c_ulong,
+ );
+ (*node).type_ = YAML_SEQUENCE_NODE;
+ (*node).tag = tag_copy;
+ (*node).start_mark = mark;
+ (*node).end_mark = mark;
+ (*node).data.sequence.items.start = items.start;
+ (*node).data.sequence.items.end = items.end;
+ (*node).data.sequence.items.top = items.start;
+ (*node).data.sequence.style = style;
+ PUSH!((*document).nodes, *node);
+ return (*document).nodes.top.c_offset_from((*document).nodes.start) as libc::c_int;
+ }
+ }
+ STACK_DEL!(items);
+ yaml_free(tag_copy as *mut libc::c_void);
+ 0
+}
+
+/// Create a MAPPING node and attach it to the document.
+///
+/// The `style` argument may be ignored by the emitter.
+///
+/// Returns the node id or 0 on error.
+#[must_use]
+pub unsafe fn yaml_document_add_mapping(
+ document: *mut yaml_document_t,
+ mut tag: *const yaml_char_t,
+ style: yaml_mapping_style_t,
+) -> libc::c_int {
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ let mut tag_copy: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ struct Pairs {
+ start: *mut yaml_node_pair_t,
+ end: *mut yaml_node_pair_t,
+ top: *mut yaml_node_pair_t,
+ }
+ let mut pairs = Pairs {
+ start: ptr::null_mut::<yaml_node_pair_t>(),
+ end: ptr::null_mut::<yaml_node_pair_t>(),
+ top: ptr::null_mut::<yaml_node_pair_t>(),
+ };
+ let mut node = MaybeUninit::<yaml_node_t>::uninit();
+ let node = node.as_mut_ptr();
+ __assert!(!document.is_null());
+ if tag.is_null() {
+ tag = b"tag:yaml.org,2002:map\0" as *const u8 as *const libc::c_char as *mut yaml_char_t;
+ }
+ if yaml_check_utf8(tag, strlen(tag as *mut libc::c_char)).ok {
+ tag_copy = yaml_strdup(tag);
+ if !tag_copy.is_null() {
+ STACK_INIT!(pairs, yaml_node_pair_t);
+ memset(
+ node as *mut libc::c_void,
+ 0,
+ size_of::<yaml_node_t>() as libc::c_ulong,
+ );
+ (*node).type_ = YAML_MAPPING_NODE;
+ (*node).tag = tag_copy;
+ (*node).start_mark = mark;
+ (*node).end_mark = mark;
+ (*node).data.mapping.pairs.start = pairs.start;
+ (*node).data.mapping.pairs.end = pairs.end;
+ (*node).data.mapping.pairs.top = pairs.start;
+ (*node).data.mapping.style = style;
+ PUSH!((*document).nodes, *node);
+ return (*document).nodes.top.c_offset_from((*document).nodes.start) as libc::c_int;
+ }
+ }
+ STACK_DEL!(pairs);
+ yaml_free(tag_copy as *mut libc::c_void);
+ 0
+}
+
+/// Add an item to a SEQUENCE node.
+pub unsafe fn yaml_document_append_sequence_item(
+ document: *mut yaml_document_t,
+ sequence: libc::c_int,
+ item: libc::c_int,
+) -> Success {
+ __assert!(!document.is_null());
+ __assert!(
+ sequence > 0
+ && ((*document).nodes.start).wrapping_offset(sequence as isize)
+ <= (*document).nodes.top
+ );
+ __assert!(
+ (*((*document).nodes.start).wrapping_offset((sequence - 1) as isize)).type_
+ == YAML_SEQUENCE_NODE
+ );
+ __assert!(
+ item > 0
+ && ((*document).nodes.start).wrapping_offset(item as isize) <= (*document).nodes.top
+ );
+ PUSH!(
+ (*((*document).nodes.start).wrapping_offset((sequence - 1) as isize))
+ .data
+ .sequence
+ .items,
+ item
+ );
+ OK
+}
+
+/// Add a pair of a key and a value to a MAPPING node.
+pub unsafe fn yaml_document_append_mapping_pair(
+ document: *mut yaml_document_t,
+ mapping: libc::c_int,
+ key: libc::c_int,
+ value: libc::c_int,
+) -> Success {
+ __assert!(!document.is_null());
+ __assert!(
+ mapping > 0
+ && ((*document).nodes.start).wrapping_offset(mapping as isize) <= (*document).nodes.top
+ );
+ __assert!(
+ (*((*document).nodes.start).wrapping_offset((mapping - 1) as isize)).type_
+ == YAML_MAPPING_NODE
+ );
+ __assert!(
+ key > 0 && ((*document).nodes.start).wrapping_offset(key as isize) <= (*document).nodes.top
+ );
+ __assert!(
+ value > 0
+ && ((*document).nodes.start).wrapping_offset(value as isize) <= (*document).nodes.top
+ );
+ let pair = yaml_node_pair_t { key, value };
+ PUSH!(
+ (*((*document).nodes.start).wrapping_offset((mapping - 1) as isize))
+ .data
+ .mapping
+ .pairs,
+ pair
+ );
+ OK
+}
diff --git a/src/bin/cstr/mod.rs b/src/bin/cstr/mod.rs
new file mode 100644
index 0000000..7054c46
--- /dev/null
+++ b/src/bin/cstr/mod.rs
@@ -0,0 +1,47 @@
+use std::fmt::{self, Display, Write as _};
+use std::slice;
+use std::str;
+
+#[allow(non_camel_case_types)]
+type c_char = i8;
+
+pub struct CStr {
+ ptr: *const u8,
+}
+
+impl CStr {
+ pub unsafe fn from_ptr(ptr: *const c_char) -> Self {
+ CStr { ptr: ptr.cast() }
+ }
+}
+
+impl Display for CStr {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let len = unsafe { strlen(self.ptr) };
+ let mut bytes = unsafe { slice::from_raw_parts(self.ptr, len) };
+ loop {
+ match str::from_utf8(bytes) {
+ Ok(valid) => return formatter.write_str(valid),
+ Err(utf8_error) => {
+ let valid_up_to = utf8_error.valid_up_to();
+ let valid = unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) };
+ formatter.write_str(valid)?;
+ formatter.write_char(char::REPLACEMENT_CHARACTER)?;
+ if let Some(error_len) = utf8_error.error_len() {
+ bytes = &bytes[valid_up_to + error_len..];
+ } else {
+ return Ok(());
+ }
+ }
+ }
+ }
+ }
+}
+
+unsafe fn strlen(s: *const u8) -> usize {
+ let mut end = s;
+ while *end != 0 {
+ end = end.add(1);
+ }
+ end.offset_from(s) as usize
+}
diff --git a/src/bin/run-emitter-test-suite.rs b/src/bin/run-emitter-test-suite.rs
new file mode 100644
index 0000000..0c51b9c
--- /dev/null
+++ b/src/bin/run-emitter-test-suite.rs
@@ -0,0 +1,307 @@
+#![warn(clippy::pedantic)]
+#![allow(
+ clippy::cast_lossless,
+ clippy::cast_possible_truncation,
+ clippy::cast_possible_wrap,
+ clippy::cast_sign_loss,
+ clippy::items_after_statements,
+ clippy::let_underscore_untyped,
+ clippy::missing_errors_doc,
+ clippy::missing_safety_doc,
+ clippy::ptr_as_ptr,
+ clippy::single_match_else,
+ clippy::too_many_lines,
+ clippy::unreadable_literal
+)]
+
+mod cstr;
+
+use self::cstr::CStr;
+use std::env;
+use std::error::Error;
+use std::ffi::c_void;
+use std::fs::File;
+use std::io::{self, Read, Write};
+use std::mem::MaybeUninit;
+use std::process::{self, ExitCode};
+use std::ptr::{self, addr_of_mut};
+use std::slice;
+use unsafe_libyaml::{
+ yaml_alias_event_initialize, yaml_document_end_event_initialize,
+ yaml_document_start_event_initialize, yaml_emitter_delete, yaml_emitter_emit,
+ yaml_emitter_initialize, yaml_emitter_set_canonical, yaml_emitter_set_output,
+ yaml_emitter_set_unicode, yaml_emitter_t, yaml_event_t, yaml_mapping_end_event_initialize,
+ yaml_mapping_start_event_initialize, yaml_scalar_event_initialize, yaml_scalar_style_t,
+ yaml_sequence_end_event_initialize, yaml_sequence_start_event_initialize,
+ yaml_stream_end_event_initialize, yaml_stream_start_event_initialize, yaml_tag_directive_t,
+ yaml_version_directive_t, YAML_ANY_SCALAR_STYLE, YAML_BLOCK_MAPPING_STYLE,
+ YAML_BLOCK_SEQUENCE_STYLE, YAML_DOUBLE_QUOTED_SCALAR_STYLE, YAML_EMITTER_ERROR,
+ YAML_FOLDED_SCALAR_STYLE, YAML_LITERAL_SCALAR_STYLE, YAML_MEMORY_ERROR,
+ YAML_PLAIN_SCALAR_STYLE, YAML_SINGLE_QUOTED_SCALAR_STYLE, YAML_UTF8_ENCODING,
+ YAML_WRITER_ERROR,
+};
+
+pub(crate) unsafe fn unsafe_main(
+ stdin: &mut dyn Read,
+ mut stdout: &mut dyn Write,
+) -> Result<(), Box<dyn Error>> {
+ let mut emitter = MaybeUninit::<yaml_emitter_t>::uninit();
+ let emitter = emitter.as_mut_ptr();
+ if yaml_emitter_initialize(emitter).fail {
+ return Err("Could not initalize the emitter object".into());
+ }
+
+ unsafe fn write_to_stdio(data: *mut c_void, buffer: *mut u8, size: u64) -> i32 {
+ let stdout: *mut &mut dyn Write = data.cast();
+ let bytes = slice::from_raw_parts(buffer.cast(), size as usize);
+ match (*stdout).write(bytes) {
+ Ok(n) => n as i32,
+ Err(_) => 0,
+ }
+ }
+
+ yaml_emitter_set_output(emitter, write_to_stdio, addr_of_mut!(stdout).cast());
+ yaml_emitter_set_canonical(emitter, false);
+ yaml_emitter_set_unicode(emitter, false);
+
+ let mut buf = ReadBuf::new();
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ let result = loop {
+ let line = match buf.get_line(stdin) {
+ Some(line) => line,
+ None => break Ok(()),
+ };
+
+ let mut anchor = [0u8; 256];
+ let mut tag = [0u8; 256];
+ let result = if line.starts_with(b"+STR") {
+ yaml_stream_start_event_initialize(event, YAML_UTF8_ENCODING)
+ } else if line.starts_with(b"-STR") {
+ yaml_stream_end_event_initialize(event)
+ } else if line.starts_with(b"+DOC") {
+ let implicit = !line[4..].starts_with(b" ---");
+ yaml_document_start_event_initialize(
+ event,
+ ptr::null_mut::<yaml_version_directive_t>(),
+ ptr::null_mut::<yaml_tag_directive_t>(),
+ ptr::null_mut::<yaml_tag_directive_t>(),
+ implicit,
+ )
+ } else if line.starts_with(b"-DOC") {
+ let implicit = !line[4..].starts_with(b" ...");
+ yaml_document_end_event_initialize(event, implicit)
+ } else if line.starts_with(b"+MAP") {
+ yaml_mapping_start_event_initialize(
+ event,
+ get_anchor(b'&', line, anchor.as_mut_ptr()),
+ get_tag(line, tag.as_mut_ptr()),
+ false,
+ YAML_BLOCK_MAPPING_STYLE,
+ )
+ } else if line.starts_with(b"-MAP") {
+ yaml_mapping_end_event_initialize(event)
+ } else if line.starts_with(b"+SEQ") {
+ yaml_sequence_start_event_initialize(
+ event,
+ get_anchor(b'&', line, anchor.as_mut_ptr()),
+ get_tag(line, tag.as_mut_ptr()),
+ false,
+ YAML_BLOCK_SEQUENCE_STYLE,
+ )
+ } else if line.starts_with(b"-SEQ") {
+ yaml_sequence_end_event_initialize(event)
+ } else if line.starts_with(b"=VAL") {
+ let mut value = [0i8; 1024];
+ let mut style = YAML_ANY_SCALAR_STYLE;
+ get_value(line, value.as_mut_ptr(), &mut style);
+ let implicit = get_tag(line, tag.as_mut_ptr()).is_null();
+ yaml_scalar_event_initialize(
+ event,
+ get_anchor(b'&', line, anchor.as_mut_ptr()),
+ get_tag(line, tag.as_mut_ptr()),
+ value.as_mut_ptr() as *mut u8,
+ -1,
+ implicit,
+ implicit,
+ style,
+ )
+ } else if line.starts_with(b"=ALI") {
+ yaml_alias_event_initialize(event, get_anchor(b'*', line, anchor.as_mut_ptr()))
+ } else {
+ let line = line as *mut [u8] as *mut i8;
+ break Err(format!("Unknown event: '{}'", CStr::from_ptr(line)).into());
+ };
+
+ if result.fail {
+ break Err("Memory error: Not enough memory for creating an event".into());
+ }
+ if yaml_emitter_emit(emitter, event).fail {
+ break Err(match (*emitter).error {
+ YAML_MEMORY_ERROR => "Memory error: Not enough memory for emitting".into(),
+ YAML_WRITER_ERROR => {
+ format!("Writer error: {}", CStr::from_ptr((*emitter).problem)).into()
+ }
+ YAML_EMITTER_ERROR => {
+ format!("Emitter error: {}", CStr::from_ptr((*emitter).problem)).into()
+ }
+ // Couldn't happen.
+ _ => "Internal error".into(),
+ });
+ }
+ };
+
+ yaml_emitter_delete(emitter);
+ result
+}
+
+struct ReadBuf {
+ buf: [u8; 1024],
+ offset: usize,
+ filled: usize,
+}
+
+impl ReadBuf {
+ fn new() -> Self {
+ ReadBuf {
+ buf: [0; 1024],
+ offset: 0,
+ filled: 0,
+ }
+ }
+
+ fn get_line(&mut self, input: &mut dyn Read) -> Option<&mut [u8]> {
+ loop {
+ for i in self.offset..self.offset + self.filled {
+ if self.buf[i] == b'\n' {
+ self.buf[i] = b'\0';
+ let line = &mut self.buf[self.offset..=i];
+ self.offset = i + 1;
+ self.filled -= line.len();
+ return Some(line);
+ }
+ }
+ let mut remainder = &mut self.buf[self.offset + self.filled..];
+ if remainder.is_empty() {
+ if self.offset == 0 {
+ let _ = writeln!(
+ io::stderr(),
+ "Line too long: '{}'",
+ String::from_utf8_lossy(&self.buf),
+ );
+ process::abort();
+ }
+ self.buf.copy_within(self.offset.., 0);
+ self.offset = 0;
+ remainder = &mut self.buf;
+ }
+ let n = input.read(remainder).ok()?;
+ self.filled += n;
+ if n == 0 {
+ return None;
+ }
+ }
+ }
+}
+
+unsafe fn get_anchor(sigil: u8, line: &[u8], anchor: *mut u8) -> *mut u8 {
+ let start = match line.iter().position(|ch| *ch == sigil) {
+ Some(offset) => offset + 1,
+ None => return ptr::null_mut::<u8>(),
+ };
+ let end = match line[start..].iter().position(|ch| *ch == b' ') {
+ Some(offset) => start + offset,
+ None => line.len(),
+ };
+ ptr::copy_nonoverlapping(line[start..end].as_ptr(), anchor, end - start);
+ *anchor.add(end - start) = b'\0';
+ anchor
+}
+
+unsafe fn get_tag(line: &[u8], tag: *mut u8) -> *mut u8 {
+ let start = match line.iter().position(|ch| *ch == b'<') {
+ Some(offset) => offset + 1,
+ None => return ptr::null_mut::<u8>(),
+ };
+ let end = match line[start..].iter().position(|ch| *ch == b'>') {
+ Some(offset) => start + offset,
+ None => return ptr::null_mut::<u8>(),
+ };
+ ptr::copy_nonoverlapping(line[start..end].as_ptr(), tag, end - start);
+ *tag.add(end - start) = b'\0';
+ tag
+}
+
+unsafe fn get_value(line: &[u8], value: *mut i8, style: *mut yaml_scalar_style_t) {
+ let line_len = line.len();
+ let line = line as *const [u8] as *mut i8;
+ let mut start = ptr::null_mut::<i8>();
+ let end = line.add(line_len);
+ let mut c = line.offset(4);
+ while c < end {
+ if *c as u8 == b' ' {
+ start = c.offset(1);
+ *style = match *start as u8 {
+ b':' => YAML_PLAIN_SCALAR_STYLE,
+ b'\'' => YAML_SINGLE_QUOTED_SCALAR_STYLE,
+ b'"' => YAML_DOUBLE_QUOTED_SCALAR_STYLE,
+ b'|' => YAML_LITERAL_SCALAR_STYLE,
+ b'>' => YAML_FOLDED_SCALAR_STYLE,
+ _ => {
+ start = ptr::null_mut::<i8>();
+ c = c.offset(1);
+ continue;
+ }
+ };
+ start = start.offset(1);
+ break;
+ }
+ c = c.offset(1);
+ }
+ if start.is_null() {
+ process::abort();
+ }
+
+ let mut i = 0;
+ c = start;
+ while c < end {
+ *value.offset(i) = if *c as u8 == b'\\' {
+ c = c.offset(1);
+ match *c as u8 {
+ b'\\' => b'\\' as i8,
+ b'0' => b'\0' as i8,
+ b'b' => b'\x08' as i8,
+ b'n' => b'\n' as i8,
+ b'r' => b'\r' as i8,
+ b't' => b'\t' as i8,
+ _ => process::abort(),
+ }
+ } else {
+ *c
+ };
+ i += 1;
+ c = c.offset(1);
+ }
+ *value.offset(i) = b'\0' as i8;
+}
+
+fn main() -> ExitCode {
+ let args = env::args_os().skip(1);
+ if args.len() == 0 {
+ let _ = writeln!(
+ io::stderr(),
+ "Usage: run-emitter-test-suite <test.event>...",
+ );
+ return ExitCode::FAILURE;
+ }
+ for arg in args {
+ let mut stdin = File::open(arg).unwrap();
+ let mut stdout = io::stdout();
+ let result = unsafe { unsafe_main(&mut stdin, &mut stdout) };
+ if let Err(err) = result {
+ let _ = writeln!(io::stderr(), "{}", err);
+ return ExitCode::FAILURE;
+ }
+ }
+ ExitCode::SUCCESS
+}
diff --git a/src/bin/run-parser-test-suite.rs b/src/bin/run-parser-test-suite.rs
new file mode 100644
index 0000000..439ee03
--- /dev/null
+++ b/src/bin/run-parser-test-suite.rs
@@ -0,0 +1,222 @@
+#![warn(clippy::pedantic)]
+#![allow(
+ clippy::cast_lossless,
+ clippy::cast_possible_truncation,
+ clippy::cast_possible_wrap,
+ clippy::cast_sign_loss,
+ clippy::items_after_statements,
+ clippy::let_underscore_untyped,
+ clippy::missing_errors_doc,
+ clippy::missing_safety_doc,
+ clippy::too_many_lines
+)]
+
+mod cstr;
+
+use self::cstr::CStr;
+use std::env;
+use std::error::Error;
+use std::ffi::c_void;
+use std::fmt::Write as _;
+use std::fs::File;
+use std::io::{self, Read, Write};
+use std::mem::MaybeUninit;
+use std::process::{self, ExitCode};
+use std::ptr::addr_of_mut;
+use std::slice;
+use unsafe_libyaml::{
+ yaml_event_delete, yaml_event_t, yaml_event_type_t, yaml_parser_delete, yaml_parser_initialize,
+ yaml_parser_parse, yaml_parser_set_input, yaml_parser_t, YAML_ALIAS_EVENT,
+ YAML_DOCUMENT_END_EVENT, YAML_DOCUMENT_START_EVENT, YAML_DOUBLE_QUOTED_SCALAR_STYLE,
+ YAML_FOLDED_SCALAR_STYLE, YAML_LITERAL_SCALAR_STYLE, YAML_MAPPING_END_EVENT,
+ YAML_MAPPING_START_EVENT, YAML_NO_EVENT, YAML_PLAIN_SCALAR_STYLE, YAML_SCALAR_EVENT,
+ YAML_SEQUENCE_END_EVENT, YAML_SEQUENCE_START_EVENT, YAML_SINGLE_QUOTED_SCALAR_STYLE,
+ YAML_STREAM_END_EVENT, YAML_STREAM_START_EVENT,
+};
+
+pub(crate) unsafe fn unsafe_main(
+ mut stdin: &mut dyn Read,
+ stdout: &mut dyn Write,
+) -> Result<(), Box<dyn Error>> {
+ let mut parser = MaybeUninit::<yaml_parser_t>::uninit();
+ let parser = parser.as_mut_ptr();
+ if yaml_parser_initialize(parser).fail {
+ return Err("Could not initialize the parser object".into());
+ }
+
+ unsafe fn read_from_stdio(
+ data: *mut c_void,
+ buffer: *mut u8,
+ size: u64,
+ size_read: *mut u64,
+ ) -> i32 {
+ let stdin: *mut &mut dyn Read = data.cast();
+ let slice = slice::from_raw_parts_mut(buffer.cast(), size as usize);
+ match (*stdin).read(slice) {
+ Ok(n) => {
+ *size_read = n as u64;
+ 1
+ }
+ Err(_) => 0,
+ }
+ }
+
+ yaml_parser_set_input(parser, read_from_stdio, addr_of_mut!(stdin).cast());
+
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ loop {
+ if yaml_parser_parse(parser, event).fail {
+ let mut error = format!("Parse error: {}", CStr::from_ptr((*parser).problem));
+ if (*parser).problem_mark.line != 0 || (*parser).problem_mark.column != 0 {
+ let _ = write!(
+ error,
+ "\nLine: {} Column: {}",
+ ((*parser).problem_mark.line).wrapping_add(1_u64),
+ ((*parser).problem_mark.column).wrapping_add(1_u64),
+ );
+ }
+ yaml_parser_delete(parser);
+ return Err(error.into());
+ }
+
+ let type_: yaml_event_type_t = (*event).type_;
+ if type_ == YAML_NO_EVENT {
+ let _ = writeln!(stdout, "???");
+ } else if type_ == YAML_STREAM_START_EVENT {
+ let _ = writeln!(stdout, "+STR");
+ } else if type_ == YAML_STREAM_END_EVENT {
+ let _ = writeln!(stdout, "-STR");
+ } else if type_ == YAML_DOCUMENT_START_EVENT {
+ let _ = write!(stdout, "+DOC");
+ if !(*event).data.document_start.implicit {
+ let _ = write!(stdout, " ---");
+ }
+ let _ = writeln!(stdout);
+ } else if type_ == YAML_DOCUMENT_END_EVENT {
+ let _ = write!(stdout, "-DOC");
+ if !(*event).data.document_end.implicit {
+ let _ = write!(stdout, " ...");
+ }
+ let _ = writeln!(stdout);
+ } else if type_ == YAML_MAPPING_START_EVENT {
+ let _ = write!(stdout, "+MAP");
+ if !(*event).data.mapping_start.anchor.is_null() {
+ let _ = write!(
+ stdout,
+ " &{}",
+ CStr::from_ptr((*event).data.mapping_start.anchor as *const i8),
+ );
+ }
+ if !(*event).data.mapping_start.tag.is_null() {
+ let _ = write!(
+ stdout,
+ " <{}>",
+ CStr::from_ptr((*event).data.mapping_start.tag as *const i8),
+ );
+ }
+ let _ = writeln!(stdout);
+ } else if type_ == YAML_MAPPING_END_EVENT {
+ let _ = writeln!(stdout, "-MAP");
+ } else if type_ == YAML_SEQUENCE_START_EVENT {
+ let _ = write!(stdout, "+SEQ");
+ if !(*event).data.sequence_start.anchor.is_null() {
+ let _ = write!(
+ stdout,
+ " &{}",
+ CStr::from_ptr((*event).data.sequence_start.anchor as *const i8),
+ );
+ }
+ if !(*event).data.sequence_start.tag.is_null() {
+ let _ = write!(
+ stdout,
+ " <{}>",
+ CStr::from_ptr((*event).data.sequence_start.tag as *const i8),
+ );
+ }
+ let _ = writeln!(stdout);
+ } else if type_ == YAML_SEQUENCE_END_EVENT {
+ let _ = writeln!(stdout, "-SEQ");
+ } else if type_ == YAML_SCALAR_EVENT {
+ let _ = write!(stdout, "=VAL");
+ if !(*event).data.scalar.anchor.is_null() {
+ let _ = write!(
+ stdout,
+ " &{}",
+ CStr::from_ptr((*event).data.scalar.anchor as *const i8),
+ );
+ }
+ if !(*event).data.scalar.tag.is_null() {
+ let _ = write!(
+ stdout,
+ " <{}>",
+ CStr::from_ptr((*event).data.scalar.tag as *const i8),
+ );
+ }
+ let _ = stdout.write_all(match (*event).data.scalar.style {
+ YAML_PLAIN_SCALAR_STYLE => b" :",
+ YAML_SINGLE_QUOTED_SCALAR_STYLE => b" '",
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE => b" \"",
+ YAML_LITERAL_SCALAR_STYLE => b" |",
+ YAML_FOLDED_SCALAR_STYLE => b" >",
+ _ => process::abort(),
+ });
+ print_escaped(
+ stdout,
+ (*event).data.scalar.value,
+ (*event).data.scalar.length,
+ );
+ let _ = writeln!(stdout);
+ } else if type_ == YAML_ALIAS_EVENT {
+ let _ = writeln!(
+ stdout,
+ "=ALI *{}",
+ CStr::from_ptr((*event).data.alias.anchor as *const i8),
+ );
+ } else {
+ process::abort();
+ }
+
+ yaml_event_delete(event);
+ if type_ == YAML_STREAM_END_EVENT {
+ break;
+ }
+ }
+ yaml_parser_delete(parser);
+ Ok(())
+}
+
+unsafe fn print_escaped(stdout: &mut dyn Write, mut str: *mut u8, length: u64) {
+ let end = str.offset(length as isize);
+ while str < end {
+ let repr = match &*str {
+ b'\\' => b"\\\\",
+ b'\0' => b"\\0",
+ b'\x08' => b"\\b",
+ b'\n' => b"\\n",
+ b'\r' => b"\\r",
+ b'\t' => b"\\t",
+ c => slice::from_ref(c),
+ };
+ let _ = stdout.write_all(repr);
+ str = str.offset(1);
+ }
+}
+
+fn main() -> ExitCode {
+ let args = env::args_os().skip(1);
+ if args.len() == 0 {
+ let _ = writeln!(io::stderr(), "Usage: run-parser-test-suite <in.yaml>...");
+ return ExitCode::FAILURE;
+ }
+ for arg in args {
+ let mut stdin = File::open(arg).unwrap();
+ let mut stdout = io::stdout();
+ let result = unsafe { unsafe_main(&mut stdin, &mut stdout) };
+ if let Err(err) = result {
+ let _ = writeln!(io::stderr(), "{}", err);
+ return ExitCode::FAILURE;
+ }
+ }
+ ExitCode::SUCCESS
+}
diff --git a/src/dumper.rs b/src/dumper.rs
new file mode 100644
index 0000000..47ebf3e
--- /dev/null
+++ b/src/dumper.rs
@@ -0,0 +1,449 @@
+use crate::api::{yaml_free, yaml_malloc};
+use crate::externs::{memset, strcmp};
+use crate::fmt::WriteToPtr;
+use crate::success::{Success, FAIL, OK};
+use crate::yaml::{
+ yaml_anchors_t, yaml_char_t, yaml_document_t, yaml_emitter_t, yaml_event_t, yaml_mark_t,
+ yaml_node_item_t, yaml_node_pair_t, yaml_node_t, YAML_ALIAS_EVENT, YAML_ANY_ENCODING,
+ YAML_DOCUMENT_END_EVENT, YAML_DOCUMENT_START_EVENT, YAML_MAPPING_END_EVENT, YAML_MAPPING_NODE,
+ YAML_MAPPING_START_EVENT, YAML_SCALAR_EVENT, YAML_SCALAR_NODE, YAML_SEQUENCE_END_EVENT,
+ YAML_SEQUENCE_NODE, YAML_SEQUENCE_START_EVENT, YAML_STREAM_END_EVENT, YAML_STREAM_START_EVENT,
+};
+use crate::{libc, yaml_document_delete, yaml_emitter_emit, PointerExt};
+use core::mem::{size_of, MaybeUninit};
+use core::ptr::{self, addr_of_mut};
+
+/// Start a YAML stream.
+///
+/// This function should be used before yaml_emitter_dump() is called.
+pub unsafe fn yaml_emitter_open(emitter: *mut yaml_emitter_t) -> Success {
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ __assert!(!emitter.is_null());
+ __assert!(!(*emitter).opened);
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_STREAM_START_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ (*event).data.stream_start.encoding = YAML_ANY_ENCODING;
+ if yaml_emitter_emit(emitter, event).fail {
+ return FAIL;
+ }
+ (*emitter).opened = true;
+ OK
+}
+
+/// Finish a YAML stream.
+///
+/// This function should be used after yaml_emitter_dump() is called.
+pub unsafe fn yaml_emitter_close(emitter: *mut yaml_emitter_t) -> Success {
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ __assert!(!emitter.is_null());
+ __assert!((*emitter).opened);
+ if (*emitter).closed {
+ return OK;
+ }
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_STREAM_END_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ if yaml_emitter_emit(emitter, event).fail {
+ return FAIL;
+ }
+ (*emitter).closed = true;
+ OK
+}
+
+/// Emit a YAML document.
+///
+/// The documen object may be generated using the yaml_parser_load() function or
+/// the yaml_document_initialize() function. The emitter takes the
+/// responsibility for the document object and destroys its content after it is
+/// emitted. The document object is destroyed even if the function fails.
+pub unsafe fn yaml_emitter_dump(
+ emitter: *mut yaml_emitter_t,
+ document: *mut yaml_document_t,
+) -> Success {
+ let current_block: u64;
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ __assert!(!emitter.is_null());
+ __assert!(!document.is_null());
+ let fresh0 = addr_of_mut!((*emitter).document);
+ *fresh0 = document;
+ if !(*emitter).opened {
+ if yaml_emitter_open(emitter).fail {
+ current_block = 5018439318894558507;
+ } else {
+ current_block = 15619007995458559411;
+ }
+ } else {
+ current_block = 15619007995458559411;
+ }
+ match current_block {
+ 15619007995458559411 => {
+ if STACK_EMPTY!((*document).nodes) {
+ if yaml_emitter_close(emitter).ok {
+ yaml_emitter_delete_document_and_anchors(emitter);
+ return OK;
+ }
+ } else {
+ __assert!((*emitter).opened);
+ let fresh1 = addr_of_mut!((*emitter).anchors);
+ *fresh1 = yaml_malloc(
+ (size_of::<yaml_anchors_t>() as libc::c_ulong)
+ .wrapping_mul((*document).nodes.top.c_offset_from((*document).nodes.start)
+ as libc::c_long as libc::c_ulong),
+ ) as *mut yaml_anchors_t;
+ memset(
+ (*emitter).anchors as *mut libc::c_void,
+ 0,
+ (size_of::<yaml_anchors_t>() as libc::c_ulong)
+ .wrapping_mul((*document).nodes.top.c_offset_from((*document).nodes.start)
+ as libc::c_long as libc::c_ulong),
+ );
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_DOCUMENT_START_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ (*event).data.document_start.version_directive = (*document).version_directive;
+ (*event).data.document_start.tag_directives.start =
+ (*document).tag_directives.start;
+ (*event).data.document_start.tag_directives.end = (*document).tag_directives.end;
+ (*event).data.document_start.implicit = (*document).start_implicit;
+ if yaml_emitter_emit(emitter, event).ok {
+ yaml_emitter_anchor_node(emitter, 1);
+ if yaml_emitter_dump_node(emitter, 1).ok {
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_DOCUMENT_END_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ (*event).data.document_end.implicit = (*document).end_implicit;
+ if yaml_emitter_emit(emitter, event).ok {
+ yaml_emitter_delete_document_and_anchors(emitter);
+ return OK;
+ }
+ }
+ }
+ }
+ }
+ _ => {}
+ }
+ yaml_emitter_delete_document_and_anchors(emitter);
+ FAIL
+}
+
+unsafe fn yaml_emitter_delete_document_and_anchors(emitter: *mut yaml_emitter_t) {
+ let mut index: libc::c_int;
+ if (*emitter).anchors.is_null() {
+ yaml_document_delete((*emitter).document);
+ let fresh2 = addr_of_mut!((*emitter).document);
+ *fresh2 = ptr::null_mut::<yaml_document_t>();
+ return;
+ }
+ index = 0;
+ while (*(*emitter).document)
+ .nodes
+ .start
+ .wrapping_offset(index as isize)
+ < (*(*emitter).document).nodes.top
+ {
+ let mut node: yaml_node_t = *(*(*emitter).document)
+ .nodes
+ .start
+ .wrapping_offset(index as isize);
+ if !(*(*emitter).anchors.wrapping_offset(index as isize)).serialized {
+ yaml_free(node.tag as *mut libc::c_void);
+ if node.type_ == YAML_SCALAR_NODE {
+ yaml_free(node.data.scalar.value as *mut libc::c_void);
+ }
+ }
+ if node.type_ == YAML_SEQUENCE_NODE {
+ STACK_DEL!(node.data.sequence.items);
+ }
+ if node.type_ == YAML_MAPPING_NODE {
+ STACK_DEL!(node.data.mapping.pairs);
+ }
+ index += 1;
+ }
+ STACK_DEL!((*(*emitter).document).nodes);
+ yaml_free((*emitter).anchors as *mut libc::c_void);
+ let fresh6 = addr_of_mut!((*emitter).anchors);
+ *fresh6 = ptr::null_mut::<yaml_anchors_t>();
+ (*emitter).last_anchor_id = 0;
+ let fresh7 = addr_of_mut!((*emitter).document);
+ *fresh7 = ptr::null_mut::<yaml_document_t>();
+}
+
+unsafe fn yaml_emitter_anchor_node_sub(emitter: *mut yaml_emitter_t, index: libc::c_int) {
+ (*((*emitter).anchors).offset((index - 1) as isize)).references += 1;
+ if (*(*emitter).anchors.offset((index - 1) as isize)).references == 2 {
+ (*emitter).last_anchor_id += 1;
+ (*(*emitter).anchors.offset((index - 1) as isize)).anchor = (*emitter).last_anchor_id;
+ }
+}
+
+unsafe fn yaml_emitter_anchor_node(emitter: *mut yaml_emitter_t, index: libc::c_int) {
+ let node: *mut yaml_node_t = (*(*emitter).document)
+ .nodes
+ .start
+ .wrapping_offset(index as isize)
+ .wrapping_offset(-1_isize);
+ let mut item: *mut yaml_node_item_t;
+ let mut pair: *mut yaml_node_pair_t;
+ let fresh8 =
+ addr_of_mut!((*((*emitter).anchors).wrapping_offset((index - 1) as isize)).references);
+ *fresh8 += 1;
+ if (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).references == 1 {
+ match (*node).type_ {
+ YAML_SEQUENCE_NODE => {
+ item = (*node).data.sequence.items.start;
+ while item < (*node).data.sequence.items.top {
+ yaml_emitter_anchor_node_sub(emitter, *item);
+ item = item.wrapping_offset(1);
+ }
+ }
+ YAML_MAPPING_NODE => {
+ pair = (*node).data.mapping.pairs.start;
+ while pair < (*node).data.mapping.pairs.top {
+ yaml_emitter_anchor_node_sub(emitter, (*pair).key);
+ yaml_emitter_anchor_node_sub(emitter, (*pair).value);
+ pair = pair.wrapping_offset(1);
+ }
+ }
+ _ => {}
+ }
+ } else if (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).references == 2 {
+ let fresh9 = addr_of_mut!((*emitter).last_anchor_id);
+ *fresh9 += 1;
+ (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).anchor = *fresh9;
+ }
+}
+
+unsafe fn yaml_emitter_generate_anchor(
+ _emitter: *mut yaml_emitter_t,
+ anchor_id: libc::c_int,
+) -> *mut yaml_char_t {
+ let anchor: *mut yaml_char_t = yaml_malloc(16_u64) as *mut yaml_char_t;
+ write!(WriteToPtr::new(anchor), "id{:03}\0", anchor_id);
+ anchor
+}
+
+unsafe fn yaml_emitter_dump_node(emitter: *mut yaml_emitter_t, index: libc::c_int) -> Success {
+ let node: *mut yaml_node_t = (*(*emitter).document)
+ .nodes
+ .start
+ .wrapping_offset(index as isize)
+ .wrapping_offset(-1_isize);
+ let anchor_id: libc::c_int = (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).anchor;
+ let mut anchor: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ if anchor_id != 0 {
+ anchor = yaml_emitter_generate_anchor(emitter, anchor_id);
+ }
+ if (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).serialized {
+ return yaml_emitter_dump_alias(emitter, anchor);
+ }
+ (*(*emitter).anchors.wrapping_offset((index - 1) as isize)).serialized = true;
+ match (*node).type_ {
+ YAML_SCALAR_NODE => yaml_emitter_dump_scalar(emitter, node, anchor),
+ YAML_SEQUENCE_NODE => yaml_emitter_dump_sequence(emitter, node, anchor),
+ YAML_MAPPING_NODE => yaml_emitter_dump_mapping(emitter, node, anchor),
+ _ => __assert!(false),
+ }
+}
+
+unsafe fn yaml_emitter_dump_alias(
+ emitter: *mut yaml_emitter_t,
+ anchor: *mut yaml_char_t,
+) -> Success {
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_ALIAS_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ (*event).data.alias.anchor = anchor;
+ yaml_emitter_emit(emitter, event)
+}
+
+unsafe fn yaml_emitter_dump_scalar(
+ emitter: *mut yaml_emitter_t,
+ node: *mut yaml_node_t,
+ anchor: *mut yaml_char_t,
+) -> Success {
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ let plain_implicit = strcmp(
+ (*node).tag as *mut libc::c_char,
+ b"tag:yaml.org,2002:str\0" as *const u8 as *const libc::c_char,
+ ) == 0;
+ let quoted_implicit = strcmp(
+ (*node).tag as *mut libc::c_char,
+ b"tag:yaml.org,2002:str\0" as *const u8 as *const libc::c_char,
+ ) == 0;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SCALAR_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ (*event).data.scalar.anchor = anchor;
+ (*event).data.scalar.tag = (*node).tag;
+ (*event).data.scalar.value = (*node).data.scalar.value;
+ (*event).data.scalar.length = (*node).data.scalar.length;
+ (*event).data.scalar.plain_implicit = plain_implicit;
+ (*event).data.scalar.quoted_implicit = quoted_implicit;
+ (*event).data.scalar.style = (*node).data.scalar.style;
+ yaml_emitter_emit(emitter, event)
+}
+
+unsafe fn yaml_emitter_dump_sequence(
+ emitter: *mut yaml_emitter_t,
+ node: *mut yaml_node_t,
+ anchor: *mut yaml_char_t,
+) -> Success {
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ let implicit = strcmp(
+ (*node).tag as *mut libc::c_char,
+ b"tag:yaml.org,2002:seq\0" as *const u8 as *const libc::c_char,
+ ) == 0;
+ let mut item: *mut yaml_node_item_t;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SEQUENCE_START_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ (*event).data.sequence_start.anchor = anchor;
+ (*event).data.sequence_start.tag = (*node).tag;
+ (*event).data.sequence_start.implicit = implicit;
+ (*event).data.sequence_start.style = (*node).data.sequence.style;
+ if yaml_emitter_emit(emitter, event).fail {
+ return FAIL;
+ }
+ item = (*node).data.sequence.items.start;
+ while item < (*node).data.sequence.items.top {
+ if yaml_emitter_dump_node(emitter, *item).fail {
+ return FAIL;
+ }
+ item = item.wrapping_offset(1);
+ }
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SEQUENCE_END_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ yaml_emitter_emit(emitter, event)
+}
+
+unsafe fn yaml_emitter_dump_mapping(
+ emitter: *mut yaml_emitter_t,
+ node: *mut yaml_node_t,
+ anchor: *mut yaml_char_t,
+) -> Success {
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ let mark = yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ };
+ let implicit = strcmp(
+ (*node).tag as *mut libc::c_char,
+ b"tag:yaml.org,2002:map\0" as *const u8 as *const libc::c_char,
+ ) == 0;
+ let mut pair: *mut yaml_node_pair_t;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_MAPPING_START_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ (*event).data.mapping_start.anchor = anchor;
+ (*event).data.mapping_start.tag = (*node).tag;
+ (*event).data.mapping_start.implicit = implicit;
+ (*event).data.mapping_start.style = (*node).data.mapping.style;
+ if yaml_emitter_emit(emitter, event).fail {
+ return FAIL;
+ }
+ pair = (*node).data.mapping.pairs.start;
+ while pair < (*node).data.mapping.pairs.top {
+ if yaml_emitter_dump_node(emitter, (*pair).key).fail {
+ return FAIL;
+ }
+ if yaml_emitter_dump_node(emitter, (*pair).value).fail {
+ return FAIL;
+ }
+ pair = pair.wrapping_offset(1);
+ }
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_MAPPING_END_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ yaml_emitter_emit(emitter, event)
+}
diff --git a/src/emitter.rs b/src/emitter.rs
new file mode 100644
index 0000000..11f5cbd
--- /dev/null
+++ b/src/emitter.rs
@@ -0,0 +1,2384 @@
+use crate::api::{yaml_free, yaml_queue_extend, yaml_stack_extend, yaml_strdup};
+use crate::externs::{strcmp, strlen, strncmp};
+use crate::success::{Success, FAIL, OK};
+use crate::yaml::{size_t, yaml_char_t, yaml_string_t};
+use crate::{
+ libc, yaml_emitter_flush, yaml_emitter_t, yaml_event_delete, yaml_event_t, yaml_scalar_style_t,
+ yaml_tag_directive_t, yaml_version_directive_t, PointerExt, YAML_ALIAS_EVENT, YAML_ANY_BREAK,
+ YAML_ANY_ENCODING, YAML_ANY_SCALAR_STYLE, YAML_CRLN_BREAK, YAML_CR_BREAK,
+ YAML_DOCUMENT_END_EVENT, YAML_DOCUMENT_START_EVENT, YAML_DOUBLE_QUOTED_SCALAR_STYLE,
+ YAML_EMITTER_ERROR, YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, YAML_EMIT_BLOCK_MAPPING_KEY_STATE,
+ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, YAML_EMIT_BLOCK_MAPPING_VALUE_STATE,
+ YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE,
+ YAML_EMIT_DOCUMENT_CONTENT_STATE, YAML_EMIT_DOCUMENT_END_STATE, YAML_EMIT_DOCUMENT_START_STATE,
+ YAML_EMIT_END_STATE, YAML_EMIT_FIRST_DOCUMENT_START_STATE,
+ YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, YAML_EMIT_FLOW_MAPPING_KEY_STATE,
+ YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, YAML_EMIT_FLOW_MAPPING_VALUE_STATE,
+ YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE,
+ YAML_EMIT_STREAM_START_STATE, YAML_FLOW_MAPPING_STYLE, YAML_FLOW_SEQUENCE_STYLE,
+ YAML_FOLDED_SCALAR_STYLE, YAML_LITERAL_SCALAR_STYLE, YAML_LN_BREAK, YAML_MAPPING_END_EVENT,
+ YAML_MAPPING_START_EVENT, YAML_PLAIN_SCALAR_STYLE, YAML_SCALAR_EVENT, YAML_SEQUENCE_END_EVENT,
+ YAML_SEQUENCE_START_EVENT, YAML_SINGLE_QUOTED_SCALAR_STYLE, YAML_STREAM_END_EVENT,
+ YAML_STREAM_START_EVENT, YAML_UTF8_ENCODING,
+};
+use core::ptr::{self, addr_of_mut};
+
+unsafe fn FLUSH(emitter: *mut yaml_emitter_t) -> Success {
+ if (*emitter).buffer.pointer.wrapping_offset(5_isize) < (*emitter).buffer.end {
+ OK
+ } else {
+ yaml_emitter_flush(emitter)
+ }
+}
+
+unsafe fn PUT(emitter: *mut yaml_emitter_t, value: u8) -> Success {
+ if FLUSH(emitter).fail {
+ return FAIL;
+ }
+ let fresh40 = addr_of_mut!((*emitter).buffer.pointer);
+ let fresh41 = *fresh40;
+ *fresh40 = (*fresh40).wrapping_offset(1);
+ *fresh41 = value;
+ let fresh42 = addr_of_mut!((*emitter).column);
+ *fresh42 += 1;
+ OK
+}
+
+unsafe fn PUT_BREAK(emitter: *mut yaml_emitter_t) -> Success {
+ if FLUSH(emitter).fail {
+ return FAIL;
+ }
+ if (*emitter).line_break == YAML_CR_BREAK {
+ let fresh62 = addr_of_mut!((*emitter).buffer.pointer);
+ let fresh63 = *fresh62;
+ *fresh62 = (*fresh62).wrapping_offset(1);
+ *fresh63 = b'\r';
+ } else if (*emitter).line_break == YAML_LN_BREAK {
+ let fresh64 = addr_of_mut!((*emitter).buffer.pointer);
+ let fresh65 = *fresh64;
+ *fresh64 = (*fresh64).wrapping_offset(1);
+ *fresh65 = b'\n';
+ } else if (*emitter).line_break == YAML_CRLN_BREAK {
+ let fresh66 = addr_of_mut!((*emitter).buffer.pointer);
+ let fresh67 = *fresh66;
+ *fresh66 = (*fresh66).wrapping_offset(1);
+ *fresh67 = b'\r';
+ let fresh68 = addr_of_mut!((*emitter).buffer.pointer);
+ let fresh69 = *fresh68;
+ *fresh68 = (*fresh68).wrapping_offset(1);
+ *fresh69 = b'\n';
+ };
+ (*emitter).column = 0;
+ let fresh70 = addr_of_mut!((*emitter).line);
+ *fresh70 += 1;
+ OK
+}
+
+unsafe fn WRITE(emitter: *mut yaml_emitter_t, string: *mut yaml_string_t) -> Success {
+ if FLUSH(emitter).fail {
+ return FAIL;
+ }
+ COPY!((*emitter).buffer, *string);
+ let fresh107 = addr_of_mut!((*emitter).column);
+ *fresh107 += 1;
+ OK
+}
+
+unsafe fn WRITE_BREAK(emitter: *mut yaml_emitter_t, string: *mut yaml_string_t) -> Success {
+ if FLUSH(emitter).fail {
+ return FAIL;
+ }
+ if CHECK!(*string, b'\n') {
+ let _ = PUT_BREAK(emitter);
+ (*string).pointer = (*string).pointer.wrapping_offset(1);
+ } else {
+ COPY!((*emitter).buffer, *string);
+ (*emitter).column = 0;
+ let fresh300 = addr_of_mut!((*emitter).line);
+ *fresh300 += 1;
+ }
+ OK
+}
+
+macro_rules! WRITE {
+ ($emitter:expr, $string:expr) => {
+ WRITE($emitter, addr_of_mut!($string))
+ };
+}
+
+macro_rules! WRITE_BREAK {
+ ($emitter:expr, $string:expr) => {
+ WRITE_BREAK($emitter, addr_of_mut!($string))
+ };
+}
+
+unsafe fn yaml_emitter_set_emitter_error(
+ emitter: *mut yaml_emitter_t,
+ problem: *const libc::c_char,
+) -> Success {
+ (*emitter).error = YAML_EMITTER_ERROR;
+ let fresh0 = addr_of_mut!((*emitter).problem);
+ *fresh0 = problem;
+ FAIL
+}
+
+/// Emit an event.
+///
+/// The event object may be generated using the yaml_parser_parse() function.
+/// The emitter takes the responsibility for the event object and destroys its
+/// content after it is emitted. The event object is destroyed even if the
+/// function fails.
+pub unsafe fn yaml_emitter_emit(emitter: *mut yaml_emitter_t, event: *mut yaml_event_t) -> Success {
+ ENQUEUE!((*emitter).events, *event);
+ while yaml_emitter_need_more_events(emitter).fail {
+ if yaml_emitter_analyze_event(emitter, (*emitter).events.head).fail {
+ return FAIL;
+ }
+ if yaml_emitter_state_machine(emitter, (*emitter).events.head).fail {
+ return FAIL;
+ }
+ yaml_event_delete(addr_of_mut!(DEQUEUE!((*emitter).events)));
+ }
+ OK
+}
+
+unsafe fn yaml_emitter_need_more_events(emitter: *mut yaml_emitter_t) -> Success {
+ let mut level: libc::c_int = 0;
+ let mut event: *mut yaml_event_t;
+ if QUEUE_EMPTY!((*emitter).events) {
+ return OK;
+ }
+ let accumulate = match (*(*emitter).events.head).type_ {
+ YAML_DOCUMENT_START_EVENT => 1,
+ YAML_SEQUENCE_START_EVENT => 2,
+ YAML_MAPPING_START_EVENT => 3,
+ _ => return FAIL,
+ };
+ if (*emitter).events.tail.c_offset_from((*emitter).events.head) as libc::c_long
+ > accumulate as libc::c_long
+ {
+ return FAIL;
+ }
+ event = (*emitter).events.head;
+ while event != (*emitter).events.tail {
+ match (*event).type_ {
+ YAML_STREAM_START_EVENT
+ | YAML_DOCUMENT_START_EVENT
+ | YAML_SEQUENCE_START_EVENT
+ | YAML_MAPPING_START_EVENT => {
+ level += 1;
+ }
+ YAML_STREAM_END_EVENT
+ | YAML_DOCUMENT_END_EVENT
+ | YAML_SEQUENCE_END_EVENT
+ | YAML_MAPPING_END_EVENT => {
+ level -= 1;
+ }
+ _ => {}
+ }
+ if level == 0 {
+ return FAIL;
+ }
+ event = event.wrapping_offset(1);
+ }
+ OK
+}
+
+unsafe fn yaml_emitter_append_tag_directive(
+ emitter: *mut yaml_emitter_t,
+ value: yaml_tag_directive_t,
+ allow_duplicates: bool,
+) -> Success {
+ let mut tag_directive: *mut yaml_tag_directive_t;
+ let mut copy = yaml_tag_directive_t {
+ handle: ptr::null_mut::<yaml_char_t>(),
+ prefix: ptr::null_mut::<yaml_char_t>(),
+ };
+ tag_directive = (*emitter).tag_directives.start;
+ while tag_directive != (*emitter).tag_directives.top {
+ if strcmp(
+ value.handle as *mut libc::c_char,
+ (*tag_directive).handle as *mut libc::c_char,
+ ) == 0
+ {
+ if allow_duplicates {
+ return OK;
+ }
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ b"duplicate %TAG directive\0" as *const u8 as *const libc::c_char,
+ );
+ }
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ copy.handle = yaml_strdup(value.handle);
+ copy.prefix = yaml_strdup(value.prefix);
+ PUSH!((*emitter).tag_directives, copy);
+ OK
+}
+
+unsafe fn yaml_emitter_increase_indent(emitter: *mut yaml_emitter_t, flow: bool, indentless: bool) {
+ PUSH!((*emitter).indents, (*emitter).indent);
+ if (*emitter).indent < 0 {
+ (*emitter).indent = if flow { (*emitter).best_indent } else { 0 };
+ } else if !indentless {
+ (*emitter).indent += (*emitter).best_indent;
+ }
+}
+
+unsafe fn yaml_emitter_state_machine(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ match (*emitter).state {
+ YAML_EMIT_STREAM_START_STATE => yaml_emitter_emit_stream_start(emitter, event),
+ YAML_EMIT_FIRST_DOCUMENT_START_STATE => {
+ yaml_emitter_emit_document_start(emitter, event, true)
+ }
+ YAML_EMIT_DOCUMENT_START_STATE => yaml_emitter_emit_document_start(emitter, event, false),
+ YAML_EMIT_DOCUMENT_CONTENT_STATE => yaml_emitter_emit_document_content(emitter, event),
+ YAML_EMIT_DOCUMENT_END_STATE => yaml_emitter_emit_document_end(emitter, event),
+ YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE => {
+ yaml_emitter_emit_flow_sequence_item(emitter, event, true)
+ }
+ YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE => {
+ yaml_emitter_emit_flow_sequence_item(emitter, event, false)
+ }
+ YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE => {
+ yaml_emitter_emit_flow_mapping_key(emitter, event, true)
+ }
+ YAML_EMIT_FLOW_MAPPING_KEY_STATE => {
+ yaml_emitter_emit_flow_mapping_key(emitter, event, false)
+ }
+ YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE => {
+ yaml_emitter_emit_flow_mapping_value(emitter, event, true)
+ }
+ YAML_EMIT_FLOW_MAPPING_VALUE_STATE => {
+ yaml_emitter_emit_flow_mapping_value(emitter, event, false)
+ }
+ YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE => {
+ yaml_emitter_emit_block_sequence_item(emitter, event, true)
+ }
+ YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE => {
+ yaml_emitter_emit_block_sequence_item(emitter, event, false)
+ }
+ YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE => {
+ yaml_emitter_emit_block_mapping_key(emitter, event, true)
+ }
+ YAML_EMIT_BLOCK_MAPPING_KEY_STATE => {
+ yaml_emitter_emit_block_mapping_key(emitter, event, false)
+ }
+ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE => {
+ yaml_emitter_emit_block_mapping_value(emitter, event, true)
+ }
+ YAML_EMIT_BLOCK_MAPPING_VALUE_STATE => {
+ yaml_emitter_emit_block_mapping_value(emitter, event, false)
+ }
+ YAML_EMIT_END_STATE => yaml_emitter_set_emitter_error(
+ emitter,
+ b"expected nothing after STREAM-END\0" as *const u8 as *const libc::c_char,
+ ),
+ }
+}
+
+unsafe fn yaml_emitter_emit_stream_start(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ (*emitter).open_ended = 0;
+ if (*event).type_ == YAML_STREAM_START_EVENT {
+ if (*emitter).encoding == YAML_ANY_ENCODING {
+ (*emitter).encoding = (*event).data.stream_start.encoding;
+ }
+ if (*emitter).encoding == YAML_ANY_ENCODING {
+ (*emitter).encoding = YAML_UTF8_ENCODING;
+ }
+ if (*emitter).best_indent < 2 || (*emitter).best_indent > 9 {
+ (*emitter).best_indent = 2;
+ }
+ if (*emitter).best_width >= 0 && (*emitter).best_width <= (*emitter).best_indent * 2 {
+ (*emitter).best_width = 80;
+ }
+ if (*emitter).best_width < 0 {
+ (*emitter).best_width = libc::c_int::MAX;
+ }
+ if (*emitter).line_break == YAML_ANY_BREAK {
+ (*emitter).line_break = YAML_LN_BREAK;
+ }
+ (*emitter).indent = -1;
+ (*emitter).line = 0;
+ (*emitter).column = 0;
+ (*emitter).whitespace = true;
+ (*emitter).indention = true;
+ if (*emitter).encoding != YAML_UTF8_ENCODING {
+ if yaml_emitter_write_bom(emitter).fail {
+ return FAIL;
+ }
+ }
+ (*emitter).state = YAML_EMIT_FIRST_DOCUMENT_START_STATE;
+ return OK;
+ }
+ yaml_emitter_set_emitter_error(
+ emitter,
+ b"expected STREAM-START\0" as *const u8 as *const libc::c_char,
+ )
+}
+
+unsafe fn yaml_emitter_emit_document_start(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+ first: bool,
+) -> Success {
+ if (*event).type_ == YAML_DOCUMENT_START_EVENT {
+ let mut default_tag_directives: [yaml_tag_directive_t; 3] = [
+ yaml_tag_directive_t {
+ handle: b"!\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
+ prefix: b"!\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
+ },
+ yaml_tag_directive_t {
+ handle: b"!!\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
+ prefix: b"tag:yaml.org,2002:\0" as *const u8 as *const libc::c_char
+ as *mut yaml_char_t,
+ },
+ yaml_tag_directive_t {
+ handle: ptr::null_mut::<yaml_char_t>(),
+ prefix: ptr::null_mut::<yaml_char_t>(),
+ },
+ ];
+ let mut tag_directive: *mut yaml_tag_directive_t;
+ let mut implicit;
+ if !(*event).data.document_start.version_directive.is_null() {
+ if yaml_emitter_analyze_version_directive(
+ emitter,
+ *(*event).data.document_start.version_directive,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ tag_directive = (*event).data.document_start.tag_directives.start;
+ while tag_directive != (*event).data.document_start.tag_directives.end {
+ if yaml_emitter_analyze_tag_directive(emitter, *tag_directive).fail {
+ return FAIL;
+ }
+ if yaml_emitter_append_tag_directive(emitter, *tag_directive, false).fail {
+ return FAIL;
+ }
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ tag_directive = default_tag_directives.as_mut_ptr();
+ while !(*tag_directive).handle.is_null() {
+ if yaml_emitter_append_tag_directive(emitter, *tag_directive, true).fail {
+ return FAIL;
+ }
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ implicit = (*event).data.document_start.implicit;
+ if !first || (*emitter).canonical {
+ implicit = false;
+ }
+ if (!(*event).data.document_start.version_directive.is_null()
+ || (*event).data.document_start.tag_directives.start
+ != (*event).data.document_start.tag_directives.end)
+ && (*emitter).open_ended != 0
+ {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"...\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ (*emitter).open_ended = 0;
+ if !(*event).data.document_start.version_directive.is_null() {
+ implicit = false;
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"%YAML\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if (*(*event).data.document_start.version_directive).minor == 1 {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"1.1\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ } else if yaml_emitter_write_indicator(
+ emitter,
+ b"1.2\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ if (*event).data.document_start.tag_directives.start
+ != (*event).data.document_start.tag_directives.end
+ {
+ implicit = false;
+ tag_directive = (*event).data.document_start.tag_directives.start;
+ while tag_directive != (*event).data.document_start.tag_directives.end {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"%TAG\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_tag_handle(
+ emitter,
+ (*tag_directive).handle,
+ strlen((*tag_directive).handle as *mut libc::c_char),
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_tag_content(
+ emitter,
+ (*tag_directive).prefix,
+ strlen((*tag_directive).prefix as *mut libc::c_char),
+ true,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ }
+ if yaml_emitter_check_empty_document(emitter) {
+ implicit = false;
+ }
+ if !implicit {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"---\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if (*emitter).canonical {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ }
+ (*emitter).state = YAML_EMIT_DOCUMENT_CONTENT_STATE;
+ (*emitter).open_ended = 0;
+ return OK;
+ } else if (*event).type_ == YAML_STREAM_END_EVENT {
+ if (*emitter).open_ended == 2 {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"...\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ (*emitter).open_ended = 0;
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ if yaml_emitter_flush(emitter).fail {
+ return FAIL;
+ }
+ (*emitter).state = YAML_EMIT_END_STATE;
+ return OK;
+ }
+ yaml_emitter_set_emitter_error(
+ emitter,
+ b"expected DOCUMENT-START or STREAM-END\0" as *const u8 as *const libc::c_char,
+ )
+}
+
+unsafe fn yaml_emitter_emit_document_content(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ PUSH!((*emitter).states, YAML_EMIT_DOCUMENT_END_STATE);
+ yaml_emitter_emit_node(emitter, event, true, false, false, false)
+}
+
+unsafe fn yaml_emitter_emit_document_end(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ if (*event).type_ == YAML_DOCUMENT_END_EVENT {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ if !(*event).data.document_end.implicit {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"...\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ (*emitter).open_ended = 0;
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ } else if (*emitter).open_ended == 0 {
+ (*emitter).open_ended = 1;
+ }
+ if yaml_emitter_flush(emitter).fail {
+ return FAIL;
+ }
+ (*emitter).state = YAML_EMIT_DOCUMENT_START_STATE;
+ while !STACK_EMPTY!((*emitter).tag_directives) {
+ let tag_directive = POP!((*emitter).tag_directives);
+ yaml_free(tag_directive.handle as *mut libc::c_void);
+ yaml_free(tag_directive.prefix as *mut libc::c_void);
+ }
+ return OK;
+ }
+ yaml_emitter_set_emitter_error(
+ emitter,
+ b"expected DOCUMENT-END\0" as *const u8 as *const libc::c_char,
+ )
+}
+
+unsafe fn yaml_emitter_emit_flow_sequence_item(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+ first: bool,
+) -> Success {
+ if first {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"[\0" as *const u8 as *const libc::c_char,
+ true,
+ true,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ yaml_emitter_increase_indent(emitter, true, false);
+ let fresh12 = addr_of_mut!((*emitter).flow_level);
+ *fresh12 += 1;
+ }
+ if (*event).type_ == YAML_SEQUENCE_END_EVENT {
+ let fresh13 = addr_of_mut!((*emitter).flow_level);
+ *fresh13 -= 1;
+ (*emitter).indent = POP!((*emitter).indents);
+ if (*emitter).canonical && !first {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b",\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"]\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ (*emitter).state = POP!((*emitter).states);
+ return OK;
+ }
+ if !first {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b",\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ if (*emitter).canonical || (*emitter).column > (*emitter).best_width {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ PUSH!((*emitter).states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE);
+ yaml_emitter_emit_node(emitter, event, false, true, false, false)
+}
+
+unsafe fn yaml_emitter_emit_flow_mapping_key(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+ first: bool,
+) -> Success {
+ if first {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"{\0" as *const u8 as *const libc::c_char,
+ true,
+ true,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ yaml_emitter_increase_indent(emitter, true, false);
+ let fresh18 = addr_of_mut!((*emitter).flow_level);
+ *fresh18 += 1;
+ }
+ if (*event).type_ == YAML_MAPPING_END_EVENT {
+ if STACK_EMPTY!((*emitter).indents) {
+ return FAIL;
+ }
+ let fresh19 = addr_of_mut!((*emitter).flow_level);
+ *fresh19 -= 1;
+ (*emitter).indent = POP!((*emitter).indents);
+ if (*emitter).canonical && !first {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b",\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"}\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ (*emitter).state = POP!((*emitter).states);
+ return OK;
+ }
+ if !first {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b",\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ if (*emitter).canonical || (*emitter).column > (*emitter).best_width {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ if !(*emitter).canonical && yaml_emitter_check_simple_key(emitter) {
+ PUSH!((*emitter).states, YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE);
+ yaml_emitter_emit_node(emitter, event, false, false, true, true)
+ } else {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"?\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ PUSH!((*emitter).states, YAML_EMIT_FLOW_MAPPING_VALUE_STATE);
+ yaml_emitter_emit_node(emitter, event, false, false, true, false)
+ }
+}
+
+unsafe fn yaml_emitter_emit_flow_mapping_value(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+ simple: bool,
+) -> Success {
+ if simple {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b":\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ } else {
+ if (*emitter).canonical || (*emitter).column > (*emitter).best_width {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ if yaml_emitter_write_indicator(
+ emitter,
+ b":\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ PUSH!((*emitter).states, YAML_EMIT_FLOW_MAPPING_KEY_STATE);
+ yaml_emitter_emit_node(emitter, event, false, false, true, false)
+}
+
+unsafe fn yaml_emitter_emit_block_sequence_item(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+ first: bool,
+) -> Success {
+ if first {
+ yaml_emitter_increase_indent(
+ emitter,
+ false,
+ (*emitter).mapping_context && !(*emitter).indention,
+ );
+ }
+ if (*event).type_ == YAML_SEQUENCE_END_EVENT {
+ (*emitter).indent = POP!((*emitter).indents);
+ (*emitter).state = POP!((*emitter).states);
+ return OK;
+ }
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"-\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ true,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ PUSH!((*emitter).states, YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE);
+ yaml_emitter_emit_node(emitter, event, false, true, false, false)
+}
+
+unsafe fn yaml_emitter_emit_block_mapping_key(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+ first: bool,
+) -> Success {
+ if first {
+ yaml_emitter_increase_indent(emitter, false, false);
+ }
+ if (*event).type_ == YAML_MAPPING_END_EVENT {
+ (*emitter).indent = POP!((*emitter).indents);
+ (*emitter).state = POP!((*emitter).states);
+ return OK;
+ }
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ if yaml_emitter_check_simple_key(emitter) {
+ PUSH!(
+ (*emitter).states,
+ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE
+ );
+ yaml_emitter_emit_node(emitter, event, false, false, true, true)
+ } else {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"?\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ true,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ PUSH!((*emitter).states, YAML_EMIT_BLOCK_MAPPING_VALUE_STATE);
+ yaml_emitter_emit_node(emitter, event, false, false, true, false)
+ }
+}
+
+unsafe fn yaml_emitter_emit_block_mapping_value(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+ simple: bool,
+) -> Success {
+ if simple {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b":\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ } else {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ if yaml_emitter_write_indicator(
+ emitter,
+ b":\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ true,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ PUSH!((*emitter).states, YAML_EMIT_BLOCK_MAPPING_KEY_STATE);
+ yaml_emitter_emit_node(emitter, event, false, false, true, false)
+}
+
+unsafe fn yaml_emitter_emit_node(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+ root: bool,
+ sequence: bool,
+ mapping: bool,
+ simple_key: bool,
+) -> Success {
+ (*emitter).root_context = root;
+ (*emitter).sequence_context = sequence;
+ (*emitter).mapping_context = mapping;
+ (*emitter).simple_key_context = simple_key;
+ match (*event).type_ {
+ YAML_ALIAS_EVENT => yaml_emitter_emit_alias(emitter, event),
+ YAML_SCALAR_EVENT => yaml_emitter_emit_scalar(emitter, event),
+ YAML_SEQUENCE_START_EVENT => yaml_emitter_emit_sequence_start(emitter, event),
+ YAML_MAPPING_START_EVENT => yaml_emitter_emit_mapping_start(emitter, event),
+ _ => yaml_emitter_set_emitter_error(
+ emitter,
+ b"expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS\0" as *const u8
+ as *const libc::c_char,
+ ),
+ }
+}
+
+unsafe fn yaml_emitter_emit_alias(
+ emitter: *mut yaml_emitter_t,
+ _event: *mut yaml_event_t,
+) -> Success {
+ if yaml_emitter_process_anchor(emitter).fail {
+ return FAIL;
+ }
+ if (*emitter).simple_key_context {
+ if PUT(emitter, b' ').fail {
+ return FAIL;
+ }
+ }
+ (*emitter).state = POP!((*emitter).states);
+ OK
+}
+
+unsafe fn yaml_emitter_emit_scalar(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ if yaml_emitter_select_scalar_style(emitter, event).fail {
+ return FAIL;
+ }
+ if yaml_emitter_process_anchor(emitter).fail {
+ return FAIL;
+ }
+ if yaml_emitter_process_tag(emitter).fail {
+ return FAIL;
+ }
+ yaml_emitter_increase_indent(emitter, true, false);
+ if yaml_emitter_process_scalar(emitter).fail {
+ return FAIL;
+ }
+ (*emitter).indent = POP!((*emitter).indents);
+ (*emitter).state = POP!((*emitter).states);
+ OK
+}
+
+unsafe fn yaml_emitter_emit_sequence_start(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ if yaml_emitter_process_anchor(emitter).fail {
+ return FAIL;
+ }
+ if yaml_emitter_process_tag(emitter).fail {
+ return FAIL;
+ }
+ if (*emitter).flow_level != 0
+ || (*emitter).canonical
+ || (*event).data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE
+ || yaml_emitter_check_empty_sequence(emitter)
+ {
+ (*emitter).state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE;
+ } else {
+ (*emitter).state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE;
+ }
+ OK
+}
+
+unsafe fn yaml_emitter_emit_mapping_start(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ if yaml_emitter_process_anchor(emitter).fail {
+ return FAIL;
+ }
+ if yaml_emitter_process_tag(emitter).fail {
+ return FAIL;
+ }
+ if (*emitter).flow_level != 0
+ || (*emitter).canonical
+ || (*event).data.mapping_start.style == YAML_FLOW_MAPPING_STYLE
+ || yaml_emitter_check_empty_mapping(emitter)
+ {
+ (*emitter).state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE;
+ } else {
+ (*emitter).state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE;
+ }
+ OK
+}
+
+unsafe fn yaml_emitter_check_empty_document(_emitter: *mut yaml_emitter_t) -> bool {
+ false
+}
+
+unsafe fn yaml_emitter_check_empty_sequence(emitter: *mut yaml_emitter_t) -> bool {
+ if ((*emitter).events.tail.c_offset_from((*emitter).events.head) as libc::c_long) < 2_i64 {
+ return false;
+ }
+ (*(*emitter).events.head).type_ == YAML_SEQUENCE_START_EVENT
+ && (*(*emitter).events.head.wrapping_offset(1_isize)).type_ == YAML_SEQUENCE_END_EVENT
+}
+
+unsafe fn yaml_emitter_check_empty_mapping(emitter: *mut yaml_emitter_t) -> bool {
+ if ((*emitter).events.tail.c_offset_from((*emitter).events.head) as libc::c_long) < 2_i64 {
+ return false;
+ }
+ (*(*emitter).events.head).type_ == YAML_MAPPING_START_EVENT
+ && (*(*emitter).events.head.wrapping_offset(1_isize)).type_ == YAML_MAPPING_END_EVENT
+}
+
+unsafe fn yaml_emitter_check_simple_key(emitter: *mut yaml_emitter_t) -> bool {
+ let event: *mut yaml_event_t = (*emitter).events.head;
+ let mut length: size_t = 0_u64;
+ match (*event).type_ {
+ YAML_ALIAS_EVENT => {
+ length = (length as libc::c_ulong).wrapping_add((*emitter).anchor_data.anchor_length)
+ as size_t as size_t;
+ }
+ YAML_SCALAR_EVENT => {
+ if (*emitter).scalar_data.multiline {
+ return false;
+ }
+ length = (length as libc::c_ulong).wrapping_add(
+ (*emitter)
+ .anchor_data
+ .anchor_length
+ .wrapping_add((*emitter).tag_data.handle_length)
+ .wrapping_add((*emitter).tag_data.suffix_length)
+ .wrapping_add((*emitter).scalar_data.length),
+ ) as size_t as size_t;
+ }
+ YAML_SEQUENCE_START_EVENT => {
+ if !yaml_emitter_check_empty_sequence(emitter) {
+ return false;
+ }
+ length = (length as libc::c_ulong).wrapping_add(
+ (*emitter)
+ .anchor_data
+ .anchor_length
+ .wrapping_add((*emitter).tag_data.handle_length)
+ .wrapping_add((*emitter).tag_data.suffix_length),
+ ) as size_t as size_t;
+ }
+ YAML_MAPPING_START_EVENT => {
+ if !yaml_emitter_check_empty_mapping(emitter) {
+ return false;
+ }
+ length = (length as libc::c_ulong).wrapping_add(
+ (*emitter)
+ .anchor_data
+ .anchor_length
+ .wrapping_add((*emitter).tag_data.handle_length)
+ .wrapping_add((*emitter).tag_data.suffix_length),
+ ) as size_t as size_t;
+ }
+ _ => return false,
+ }
+ if length > 128_u64 {
+ return false;
+ }
+ true
+}
+
+unsafe fn yaml_emitter_select_scalar_style(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let mut style: yaml_scalar_style_t = (*event).data.scalar.style;
+ let no_tag = (*emitter).tag_data.handle.is_null() && (*emitter).tag_data.suffix.is_null();
+ if no_tag && !(*event).data.scalar.plain_implicit && !(*event).data.scalar.quoted_implicit {
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ b"neither tag nor implicit flags are specified\0" as *const u8 as *const libc::c_char,
+ );
+ }
+ if style == YAML_ANY_SCALAR_STYLE {
+ style = YAML_PLAIN_SCALAR_STYLE;
+ }
+ if (*emitter).canonical {
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+ }
+ if (*emitter).simple_key_context && (*emitter).scalar_data.multiline {
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+ }
+ if style == YAML_PLAIN_SCALAR_STYLE {
+ if (*emitter).flow_level != 0 && !(*emitter).scalar_data.flow_plain_allowed
+ || (*emitter).flow_level == 0 && !(*emitter).scalar_data.block_plain_allowed
+ {
+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+ }
+ if (*emitter).scalar_data.length == 0
+ && ((*emitter).flow_level != 0 || (*emitter).simple_key_context)
+ {
+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+ }
+ if no_tag && !(*event).data.scalar.plain_implicit {
+ style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
+ }
+ }
+ if style == YAML_SINGLE_QUOTED_SCALAR_STYLE {
+ if !(*emitter).scalar_data.single_quoted_allowed {
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+ }
+ }
+ if style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE {
+ if !(*emitter).scalar_data.block_allowed
+ || (*emitter).flow_level != 0
+ || (*emitter).simple_key_context
+ {
+ style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+ }
+ }
+ if no_tag && !(*event).data.scalar.quoted_implicit && style != YAML_PLAIN_SCALAR_STYLE {
+ let fresh46 = addr_of_mut!((*emitter).tag_data.handle);
+ *fresh46 = b"!\0" as *const u8 as *const libc::c_char as *mut yaml_char_t;
+ (*emitter).tag_data.handle_length = 1_u64;
+ }
+ (*emitter).scalar_data.style = style;
+ OK
+}
+
+unsafe fn yaml_emitter_process_anchor(emitter: *mut yaml_emitter_t) -> Success {
+ if (*emitter).anchor_data.anchor.is_null() {
+ return OK;
+ }
+ if yaml_emitter_write_indicator(
+ emitter,
+ if (*emitter).anchor_data.alias {
+ b"*\0" as *const u8 as *const libc::c_char
+ } else {
+ b"&\0" as *const u8 as *const libc::c_char
+ },
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ yaml_emitter_write_anchor(
+ emitter,
+ (*emitter).anchor_data.anchor,
+ (*emitter).anchor_data.anchor_length,
+ )
+}
+
+unsafe fn yaml_emitter_process_tag(emitter: *mut yaml_emitter_t) -> Success {
+ if (*emitter).tag_data.handle.is_null() && (*emitter).tag_data.suffix.is_null() {
+ return OK;
+ }
+ if !(*emitter).tag_data.handle.is_null() {
+ if yaml_emitter_write_tag_handle(
+ emitter,
+ (*emitter).tag_data.handle,
+ (*emitter).tag_data.handle_length,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if !(*emitter).tag_data.suffix.is_null() {
+ if yaml_emitter_write_tag_content(
+ emitter,
+ (*emitter).tag_data.suffix,
+ (*emitter).tag_data.suffix_length,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ } else {
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"!<\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_tag_content(
+ emitter,
+ (*emitter).tag_data.suffix,
+ (*emitter).tag_data.suffix_length,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_indicator(
+ emitter,
+ b">\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ OK
+}
+
+unsafe fn yaml_emitter_process_scalar(emitter: *mut yaml_emitter_t) -> Success {
+ match (*emitter).scalar_data.style {
+ YAML_PLAIN_SCALAR_STYLE => {
+ return yaml_emitter_write_plain_scalar(
+ emitter,
+ (*emitter).scalar_data.value,
+ (*emitter).scalar_data.length,
+ !(*emitter).simple_key_context,
+ );
+ }
+ YAML_SINGLE_QUOTED_SCALAR_STYLE => {
+ return yaml_emitter_write_single_quoted_scalar(
+ emitter,
+ (*emitter).scalar_data.value,
+ (*emitter).scalar_data.length,
+ !(*emitter).simple_key_context,
+ );
+ }
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE => {
+ return yaml_emitter_write_double_quoted_scalar(
+ emitter,
+ (*emitter).scalar_data.value,
+ (*emitter).scalar_data.length,
+ !(*emitter).simple_key_context,
+ );
+ }
+ YAML_LITERAL_SCALAR_STYLE => {
+ return yaml_emitter_write_literal_scalar(
+ emitter,
+ (*emitter).scalar_data.value,
+ (*emitter).scalar_data.length,
+ );
+ }
+ YAML_FOLDED_SCALAR_STYLE => {
+ return yaml_emitter_write_folded_scalar(
+ emitter,
+ (*emitter).scalar_data.value,
+ (*emitter).scalar_data.length,
+ );
+ }
+ _ => {}
+ }
+ FAIL
+}
+
+unsafe fn yaml_emitter_analyze_version_directive(
+ emitter: *mut yaml_emitter_t,
+ version_directive: yaml_version_directive_t,
+) -> Success {
+ if version_directive.major != 1 || version_directive.minor != 1 && version_directive.minor != 2
+ {
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ b"incompatible %YAML directive\0" as *const u8 as *const libc::c_char,
+ );
+ }
+ OK
+}
+
+unsafe fn yaml_emitter_analyze_tag_directive(
+ emitter: *mut yaml_emitter_t,
+ tag_directive: yaml_tag_directive_t,
+) -> Success {
+ let handle_length: size_t = strlen(tag_directive.handle as *mut libc::c_char);
+ let prefix_length: size_t = strlen(tag_directive.prefix as *mut libc::c_char);
+ let mut handle = STRING_ASSIGN!(tag_directive.handle, handle_length);
+ let prefix = STRING_ASSIGN!(tag_directive.prefix, prefix_length);
+ if handle.start == handle.end {
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ b"tag handle must not be empty\0" as *const u8 as *const libc::c_char,
+ );
+ }
+ if *handle.start != b'!' {
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ b"tag handle must start with '!'\0" as *const u8 as *const libc::c_char,
+ );
+ }
+ if *handle.end.wrapping_offset(-1_isize) != b'!' {
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ b"tag handle must end with '!'\0" as *const u8 as *const libc::c_char,
+ );
+ }
+ handle.pointer = handle.pointer.wrapping_offset(1);
+ while handle.pointer < handle.end.wrapping_offset(-1_isize) {
+ if !IS_ALPHA!(handle) {
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ b"tag handle must contain alphanumerical characters only\0" as *const u8
+ as *const libc::c_char,
+ );
+ }
+ MOVE!(handle);
+ }
+ if prefix.start == prefix.end {
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ b"tag prefix must not be empty\0" as *const u8 as *const libc::c_char,
+ );
+ }
+ OK
+}
+
+unsafe fn yaml_emitter_analyze_anchor(
+ emitter: *mut yaml_emitter_t,
+ anchor: *mut yaml_char_t,
+ alias: bool,
+) -> Success {
+ let anchor_length: size_t = strlen(anchor as *mut libc::c_char);
+ let mut string = STRING_ASSIGN!(anchor, anchor_length);
+ if string.start == string.end {
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ if alias {
+ b"alias value must not be empty\0" as *const u8 as *const libc::c_char
+ } else {
+ b"anchor value must not be empty\0" as *const u8 as *const libc::c_char
+ },
+ );
+ }
+ while string.pointer != string.end {
+ if !IS_ALPHA!(string) {
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ if alias {
+ b"alias value must contain alphanumerical characters only\0" as *const u8
+ as *const libc::c_char
+ } else {
+ b"anchor value must contain alphanumerical characters only\0" as *const u8
+ as *const libc::c_char
+ },
+ );
+ }
+ MOVE!(string);
+ }
+ let fresh47 = addr_of_mut!((*emitter).anchor_data.anchor);
+ *fresh47 = string.start;
+ (*emitter).anchor_data.anchor_length =
+ string.end.c_offset_from(string.start) as libc::c_long as size_t;
+ (*emitter).anchor_data.alias = alias;
+ OK
+}
+
+unsafe fn yaml_emitter_analyze_tag(emitter: *mut yaml_emitter_t, tag: *mut yaml_char_t) -> Success {
+ let mut tag_directive: *mut yaml_tag_directive_t;
+ let tag_length: size_t = strlen(tag as *mut libc::c_char);
+ let string = STRING_ASSIGN!(tag, tag_length);
+ if string.start == string.end {
+ return yaml_emitter_set_emitter_error(
+ emitter,
+ b"tag value must not be empty\0" as *const u8 as *const libc::c_char,
+ );
+ }
+ tag_directive = (*emitter).tag_directives.start;
+ while tag_directive != (*emitter).tag_directives.top {
+ let prefix_length: size_t = strlen((*tag_directive).prefix as *mut libc::c_char);
+ if prefix_length < string.end.c_offset_from(string.start) as libc::c_long as size_t
+ && strncmp(
+ (*tag_directive).prefix as *mut libc::c_char,
+ string.start as *mut libc::c_char,
+ prefix_length,
+ ) == 0
+ {
+ let fresh48 = addr_of_mut!((*emitter).tag_data.handle);
+ *fresh48 = (*tag_directive).handle;
+ (*emitter).tag_data.handle_length =
+ strlen((*tag_directive).handle as *mut libc::c_char);
+ let fresh49 = addr_of_mut!((*emitter).tag_data.suffix);
+ *fresh49 = string.start.wrapping_offset(prefix_length as isize);
+ (*emitter).tag_data.suffix_length = (string.end.c_offset_from(string.start)
+ as libc::c_long as libc::c_ulong)
+ .wrapping_sub(prefix_length);
+ return OK;
+ }
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ let fresh50 = addr_of_mut!((*emitter).tag_data.suffix);
+ *fresh50 = string.start;
+ (*emitter).tag_data.suffix_length =
+ string.end.c_offset_from(string.start) as libc::c_long as size_t;
+ OK
+}
+
+unsafe fn yaml_emitter_analyze_scalar(
+ emitter: *mut yaml_emitter_t,
+ value: *mut yaml_char_t,
+ length: size_t,
+) -> Success {
+ let mut block_indicators = false;
+ let mut flow_indicators = false;
+ let mut line_breaks = false;
+ let mut special_characters = false;
+ let mut leading_space = false;
+ let mut leading_break = false;
+ let mut trailing_space = false;
+ let mut trailing_break = false;
+ let mut break_space = false;
+ let mut space_break = false;
+ let mut preceded_by_whitespace;
+ let mut followed_by_whitespace;
+ let mut previous_space = false;
+ let mut previous_break = false;
+ let mut string = STRING_ASSIGN!(value, length);
+ let fresh51 = addr_of_mut!((*emitter).scalar_data.value);
+ *fresh51 = value;
+ (*emitter).scalar_data.length = length;
+ if string.start == string.end {
+ (*emitter).scalar_data.multiline = false;
+ (*emitter).scalar_data.flow_plain_allowed = false;
+ (*emitter).scalar_data.block_plain_allowed = true;
+ (*emitter).scalar_data.single_quoted_allowed = true;
+ (*emitter).scalar_data.block_allowed = false;
+ return OK;
+ }
+ if CHECK_AT!(string, b'-', 0) && CHECK_AT!(string, b'-', 1) && CHECK_AT!(string, b'-', 2)
+ || CHECK_AT!(string, b'.', 0) && CHECK_AT!(string, b'.', 1) && CHECK_AT!(string, b'.', 2)
+ {
+ block_indicators = true;
+ flow_indicators = true;
+ }
+ preceded_by_whitespace = true;
+ followed_by_whitespace = IS_BLANKZ_AT!(string, WIDTH!(string));
+ while string.pointer != string.end {
+ if string.start == string.pointer {
+ if CHECK!(string, b'#')
+ || CHECK!(string, b',')
+ || CHECK!(string, b'[')
+ || CHECK!(string, b']')
+ || CHECK!(string, b'{')
+ || CHECK!(string, b'}')
+ || CHECK!(string, b'&')
+ || CHECK!(string, b'*')
+ || CHECK!(string, b'!')
+ || CHECK!(string, b'|')
+ || CHECK!(string, b'>')
+ || CHECK!(string, b'\'')
+ || CHECK!(string, b'"')
+ || CHECK!(string, b'%')
+ || CHECK!(string, b'@')
+ || CHECK!(string, b'`')
+ {
+ flow_indicators = true;
+ block_indicators = true;
+ }
+ if CHECK!(string, b'?') || CHECK!(string, b':') {
+ flow_indicators = true;
+ if followed_by_whitespace {
+ block_indicators = true;
+ }
+ }
+ if CHECK!(string, b'-') && followed_by_whitespace {
+ flow_indicators = true;
+ block_indicators = true;
+ }
+ } else {
+ if CHECK!(string, b',')
+ || CHECK!(string, b'?')
+ || CHECK!(string, b'[')
+ || CHECK!(string, b']')
+ || CHECK!(string, b'{')
+ || CHECK!(string, b'}')
+ {
+ flow_indicators = true;
+ }
+ if CHECK!(string, b':') {
+ flow_indicators = true;
+ if followed_by_whitespace {
+ block_indicators = true;
+ }
+ }
+ if CHECK!(string, b'#') && preceded_by_whitespace {
+ flow_indicators = true;
+ block_indicators = true;
+ }
+ }
+ if !IS_PRINTABLE!(string) || !IS_ASCII!(string) && !(*emitter).unicode {
+ special_characters = true;
+ }
+ if IS_BREAK!(string) {
+ line_breaks = true;
+ }
+ if IS_SPACE!(string) {
+ if string.start == string.pointer {
+ leading_space = true;
+ }
+ if string.pointer.wrapping_offset(WIDTH!(string) as isize) == string.end {
+ trailing_space = true;
+ }
+ if previous_break {
+ break_space = true;
+ }
+ previous_space = true;
+ previous_break = false;
+ } else if IS_BREAK!(string) {
+ if string.start == string.pointer {
+ leading_break = true;
+ }
+ if string.pointer.wrapping_offset(WIDTH!(string) as isize) == string.end {
+ trailing_break = true;
+ }
+ if previous_space {
+ space_break = true;
+ }
+ previous_space = false;
+ previous_break = true;
+ } else {
+ previous_space = false;
+ previous_break = false;
+ }
+ preceded_by_whitespace = IS_BLANKZ!(string);
+ MOVE!(string);
+ if string.pointer != string.end {
+ followed_by_whitespace = IS_BLANKZ_AT!(string, WIDTH!(string));
+ }
+ }
+ (*emitter).scalar_data.multiline = line_breaks;
+ (*emitter).scalar_data.flow_plain_allowed = true;
+ (*emitter).scalar_data.block_plain_allowed = true;
+ (*emitter).scalar_data.single_quoted_allowed = true;
+ (*emitter).scalar_data.block_allowed = true;
+ if leading_space || leading_break || trailing_space || trailing_break {
+ (*emitter).scalar_data.flow_plain_allowed = false;
+ (*emitter).scalar_data.block_plain_allowed = false;
+ }
+ if trailing_space {
+ (*emitter).scalar_data.block_allowed = false;
+ }
+ if break_space {
+ (*emitter).scalar_data.flow_plain_allowed = false;
+ (*emitter).scalar_data.block_plain_allowed = false;
+ (*emitter).scalar_data.single_quoted_allowed = false;
+ }
+ if space_break || special_characters {
+ (*emitter).scalar_data.flow_plain_allowed = false;
+ (*emitter).scalar_data.block_plain_allowed = false;
+ (*emitter).scalar_data.single_quoted_allowed = false;
+ (*emitter).scalar_data.block_allowed = false;
+ }
+ if line_breaks {
+ (*emitter).scalar_data.flow_plain_allowed = false;
+ (*emitter).scalar_data.block_plain_allowed = false;
+ }
+ if flow_indicators {
+ (*emitter).scalar_data.flow_plain_allowed = false;
+ }
+ if block_indicators {
+ (*emitter).scalar_data.block_plain_allowed = false;
+ }
+ OK
+}
+
+unsafe fn yaml_emitter_analyze_event(
+ emitter: *mut yaml_emitter_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let fresh52 = addr_of_mut!((*emitter).anchor_data.anchor);
+ *fresh52 = ptr::null_mut::<yaml_char_t>();
+ (*emitter).anchor_data.anchor_length = 0_u64;
+ let fresh53 = addr_of_mut!((*emitter).tag_data.handle);
+ *fresh53 = ptr::null_mut::<yaml_char_t>();
+ (*emitter).tag_data.handle_length = 0_u64;
+ let fresh54 = addr_of_mut!((*emitter).tag_data.suffix);
+ *fresh54 = ptr::null_mut::<yaml_char_t>();
+ (*emitter).tag_data.suffix_length = 0_u64;
+ let fresh55 = addr_of_mut!((*emitter).scalar_data.value);
+ *fresh55 = ptr::null_mut::<yaml_char_t>();
+ (*emitter).scalar_data.length = 0_u64;
+ match (*event).type_ {
+ YAML_ALIAS_EVENT => yaml_emitter_analyze_anchor(emitter, (*event).data.alias.anchor, true),
+ YAML_SCALAR_EVENT => {
+ if !(*event).data.scalar.anchor.is_null() {
+ if yaml_emitter_analyze_anchor(emitter, (*event).data.scalar.anchor, false).fail {
+ return FAIL;
+ }
+ }
+ if !(*event).data.scalar.tag.is_null()
+ && ((*emitter).canonical
+ || !(*event).data.scalar.plain_implicit
+ && !(*event).data.scalar.quoted_implicit)
+ {
+ if yaml_emitter_analyze_tag(emitter, (*event).data.scalar.tag).fail {
+ return FAIL;
+ }
+ }
+ yaml_emitter_analyze_scalar(
+ emitter,
+ (*event).data.scalar.value,
+ (*event).data.scalar.length,
+ )
+ }
+ YAML_SEQUENCE_START_EVENT => {
+ if !(*event).data.sequence_start.anchor.is_null() {
+ if yaml_emitter_analyze_anchor(emitter, (*event).data.sequence_start.anchor, false)
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ if !(*event).data.sequence_start.tag.is_null()
+ && ((*emitter).canonical || !(*event).data.sequence_start.implicit)
+ {
+ if yaml_emitter_analyze_tag(emitter, (*event).data.sequence_start.tag).fail {
+ return FAIL;
+ }
+ }
+ OK
+ }
+ YAML_MAPPING_START_EVENT => {
+ if !(*event).data.mapping_start.anchor.is_null() {
+ if yaml_emitter_analyze_anchor(emitter, (*event).data.mapping_start.anchor, false)
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ if !(*event).data.mapping_start.tag.is_null()
+ && ((*emitter).canonical || !(*event).data.mapping_start.implicit)
+ {
+ if yaml_emitter_analyze_tag(emitter, (*event).data.mapping_start.tag).fail {
+ return FAIL;
+ }
+ }
+ OK
+ }
+ _ => OK,
+ }
+}
+
+unsafe fn yaml_emitter_write_bom(emitter: *mut yaml_emitter_t) -> Success {
+ if FLUSH(emitter).fail {
+ return FAIL;
+ }
+ let fresh56 = addr_of_mut!((*emitter).buffer.pointer);
+ let fresh57 = *fresh56;
+ *fresh56 = (*fresh56).wrapping_offset(1);
+ *fresh57 = b'\xEF';
+ let fresh58 = addr_of_mut!((*emitter).buffer.pointer);
+ let fresh59 = *fresh58;
+ *fresh58 = (*fresh58).wrapping_offset(1);
+ *fresh59 = b'\xBB';
+ let fresh60 = addr_of_mut!((*emitter).buffer.pointer);
+ let fresh61 = *fresh60;
+ *fresh60 = (*fresh60).wrapping_offset(1);
+ *fresh61 = b'\xBF';
+ OK
+}
+
+unsafe fn yaml_emitter_write_indent(emitter: *mut yaml_emitter_t) -> Success {
+ let indent: libc::c_int = if (*emitter).indent >= 0 {
+ (*emitter).indent
+ } else {
+ 0
+ };
+ if !(*emitter).indention
+ || (*emitter).column > indent
+ || (*emitter).column == indent && !(*emitter).whitespace
+ {
+ if PUT_BREAK(emitter).fail {
+ return FAIL;
+ }
+ }
+ while (*emitter).column < indent {
+ if PUT(emitter, b' ').fail {
+ return FAIL;
+ }
+ }
+ (*emitter).whitespace = true;
+ (*emitter).indention = true;
+ OK
+}
+
+unsafe fn yaml_emitter_write_indicator(
+ emitter: *mut yaml_emitter_t,
+ indicator: *const libc::c_char,
+ need_whitespace: bool,
+ is_whitespace: bool,
+ is_indention: bool,
+) -> Success {
+ let indicator_length: size_t = strlen(indicator);
+ let mut string = STRING_ASSIGN!(indicator as *mut yaml_char_t, indicator_length);
+ if need_whitespace && !(*emitter).whitespace {
+ if PUT(emitter, b' ').fail {
+ return FAIL;
+ }
+ }
+ while string.pointer != string.end {
+ if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ }
+ (*emitter).whitespace = is_whitespace;
+ (*emitter).indention = (*emitter).indention && is_indention;
+ OK
+}
+
+unsafe fn yaml_emitter_write_anchor(
+ emitter: *mut yaml_emitter_t,
+ value: *mut yaml_char_t,
+ length: size_t,
+) -> Success {
+ let mut string = STRING_ASSIGN!(value, length);
+ while string.pointer != string.end {
+ if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ }
+ (*emitter).whitespace = false;
+ (*emitter).indention = false;
+ OK
+}
+
+unsafe fn yaml_emitter_write_tag_handle(
+ emitter: *mut yaml_emitter_t,
+ value: *mut yaml_char_t,
+ length: size_t,
+) -> Success {
+ let mut string = STRING_ASSIGN!(value, length);
+ if !(*emitter).whitespace {
+ if PUT(emitter, b' ').fail {
+ return FAIL;
+ }
+ }
+ while string.pointer != string.end {
+ if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ }
+ (*emitter).whitespace = false;
+ (*emitter).indention = false;
+ OK
+}
+
+unsafe fn yaml_emitter_write_tag_content(
+ emitter: *mut yaml_emitter_t,
+ value: *mut yaml_char_t,
+ length: size_t,
+ need_whitespace: bool,
+) -> Success {
+ let mut string = STRING_ASSIGN!(value, length);
+ if need_whitespace && !(*emitter).whitespace {
+ if PUT(emitter, b' ').fail {
+ return FAIL;
+ }
+ }
+ while string.pointer != string.end {
+ if IS_ALPHA!(string)
+ || CHECK!(string, b';')
+ || CHECK!(string, b'/')
+ || CHECK!(string, b'?')
+ || CHECK!(string, b':')
+ || CHECK!(string, b'@')
+ || CHECK!(string, b'&')
+ || CHECK!(string, b'=')
+ || CHECK!(string, b'+')
+ || CHECK!(string, b'$')
+ || CHECK!(string, b',')
+ || CHECK!(string, b'_')
+ || CHECK!(string, b'.')
+ || CHECK!(string, b'~')
+ || CHECK!(string, b'*')
+ || CHECK!(string, b'\'')
+ || CHECK!(string, b'(')
+ || CHECK!(string, b')')
+ || CHECK!(string, b'[')
+ || CHECK!(string, b']')
+ {
+ if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ } else {
+ let mut width = WIDTH!(string);
+ loop {
+ let fresh207 = width;
+ width -= 1;
+ if !(fresh207 != 0) {
+ break;
+ }
+ let fresh208 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ let value = *fresh208;
+ if PUT(emitter, b'%').fail {
+ return FAIL;
+ }
+ if PUT(
+ emitter,
+ (value >> 4).wrapping_add(if (value >> 4) < 10 { b'0' } else { b'A' - 10 }),
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if PUT(
+ emitter,
+ (value & 0x0F).wrapping_add(if (value & 0x0F) < 10 { b'0' } else { b'A' - 10 }),
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ }
+ }
+ (*emitter).whitespace = false;
+ (*emitter).indention = false;
+ OK
+}
+
+unsafe fn yaml_emitter_write_plain_scalar(
+ emitter: *mut yaml_emitter_t,
+ value: *mut yaml_char_t,
+ length: size_t,
+ allow_breaks: bool,
+) -> Success {
+ let mut spaces = false;
+ let mut breaks = false;
+ let mut string = STRING_ASSIGN!(value, length);
+ if !(*emitter).whitespace && (length != 0 || (*emitter).flow_level != 0) {
+ if PUT(emitter, b' ').fail {
+ return FAIL;
+ }
+ }
+ while string.pointer != string.end {
+ if IS_SPACE!(string) {
+ if allow_breaks
+ && !spaces
+ && (*emitter).column > (*emitter).best_width
+ && !IS_SPACE_AT!(string, 1)
+ {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ MOVE!(string);
+ } else if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ spaces = true;
+ } else if IS_BREAK!(string) {
+ if !breaks && CHECK!(string, b'\n') {
+ if PUT_BREAK(emitter).fail {
+ return FAIL;
+ }
+ }
+ if WRITE_BREAK!(emitter, string).fail {
+ return FAIL;
+ }
+ (*emitter).indention = true;
+ breaks = true;
+ } else {
+ if breaks {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ (*emitter).indention = false;
+ spaces = false;
+ breaks = false;
+ }
+ }
+ (*emitter).whitespace = false;
+ (*emitter).indention = false;
+ OK
+}
+
+unsafe fn yaml_emitter_write_single_quoted_scalar(
+ emitter: *mut yaml_emitter_t,
+ value: *mut yaml_char_t,
+ length: size_t,
+ allow_breaks: bool,
+) -> Success {
+ let mut spaces = false;
+ let mut breaks = false;
+ let mut string = STRING_ASSIGN!(value, length);
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"'\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ while string.pointer != string.end {
+ if IS_SPACE!(string) {
+ if allow_breaks
+ && !spaces
+ && (*emitter).column > (*emitter).best_width
+ && string.pointer != string.start
+ && string.pointer != string.end.wrapping_offset(-1_isize)
+ && !IS_SPACE_AT!(string, 1)
+ {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ MOVE!(string);
+ } else if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ spaces = true;
+ } else if IS_BREAK!(string) {
+ if !breaks && CHECK!(string, b'\n') {
+ if PUT_BREAK(emitter).fail {
+ return FAIL;
+ }
+ }
+ if WRITE_BREAK!(emitter, string).fail {
+ return FAIL;
+ }
+ (*emitter).indention = true;
+ breaks = true;
+ } else {
+ if breaks {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ if CHECK!(string, b'\'') {
+ if PUT(emitter, b'\'').fail {
+ return FAIL;
+ }
+ }
+ if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ (*emitter).indention = false;
+ spaces = false;
+ breaks = false;
+ }
+ }
+ if breaks {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"'\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ (*emitter).whitespace = false;
+ (*emitter).indention = false;
+ OK
+}
+
+unsafe fn yaml_emitter_write_double_quoted_scalar(
+ emitter: *mut yaml_emitter_t,
+ value: *mut yaml_char_t,
+ length: size_t,
+ allow_breaks: bool,
+) -> Success {
+ let mut spaces = false;
+ let mut string = STRING_ASSIGN!(value, length);
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"\"\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ while string.pointer != string.end {
+ if !IS_PRINTABLE!(string)
+ || !(*emitter).unicode && !IS_ASCII!(string)
+ || IS_BOM!(string)
+ || IS_BREAK!(string)
+ || CHECK!(string, b'"')
+ || CHECK!(string, b'\\')
+ {
+ let mut octet: libc::c_uchar;
+ let mut width: libc::c_uint;
+ let mut value_0: libc::c_uint;
+ let mut k: libc::c_int;
+ octet = *string.pointer;
+ width = if octet & 0x80 == 0x00 {
+ 1
+ } else if octet & 0xE0 == 0xC0 {
+ 2
+ } else if octet & 0xF0 == 0xE0 {
+ 3
+ } else if octet & 0xF8 == 0xF0 {
+ 4
+ } else {
+ 0
+ };
+ value_0 = if octet & 0x80 == 0 {
+ octet & 0x7F
+ } else if octet & 0xE0 == 0xC0 {
+ octet & 0x1F
+ } else if octet & 0xF0 == 0xE0 {
+ octet & 0x0F
+ } else if octet & 0xF8 == 0xF0 {
+ octet & 0x07
+ } else {
+ 0
+ } as libc::c_uint;
+ k = 1;
+ while k < width as libc::c_int {
+ octet = *string.pointer.wrapping_offset(k as isize);
+ value_0 = (value_0 << 6).wrapping_add((octet & 0x3F) as libc::c_uint);
+ k += 1;
+ }
+ string.pointer = string.pointer.wrapping_offset(width as isize);
+ if PUT(emitter, b'\\').fail {
+ return FAIL;
+ }
+ match value_0 {
+ 0x00 => {
+ if PUT(emitter, b'0').fail {
+ return FAIL;
+ }
+ }
+ 0x07 => {
+ if PUT(emitter, b'a').fail {
+ return FAIL;
+ }
+ }
+ 0x08 => {
+ if PUT(emitter, b'b').fail {
+ return FAIL;
+ }
+ }
+ 0x09 => {
+ if PUT(emitter, b't').fail {
+ return FAIL;
+ }
+ }
+ 0x0A => {
+ if PUT(emitter, b'n').fail {
+ return FAIL;
+ }
+ }
+ 0x0B => {
+ if PUT(emitter, b'v').fail {
+ return FAIL;
+ }
+ }
+ 0x0C => {
+ if PUT(emitter, b'f').fail {
+ return FAIL;
+ }
+ }
+ 0x0D => {
+ if PUT(emitter, b'r').fail {
+ return FAIL;
+ }
+ }
+ 0x1B => {
+ if PUT(emitter, b'e').fail {
+ return FAIL;
+ }
+ }
+ 0x22 => {
+ if PUT(emitter, b'"').fail {
+ return FAIL;
+ }
+ }
+ 0x5C => {
+ if PUT(emitter, b'\\').fail {
+ return FAIL;
+ }
+ }
+ 0x85 => {
+ if PUT(emitter, b'N').fail {
+ return FAIL;
+ }
+ }
+ 0xA0 => {
+ if PUT(emitter, b'_').fail {
+ return FAIL;
+ }
+ }
+ 0x2028 => {
+ if PUT(emitter, b'L').fail {
+ return FAIL;
+ }
+ }
+ 0x2029 => {
+ if PUT(emitter, b'P').fail {
+ return FAIL;
+ }
+ }
+ _ => {
+ if value_0 <= 0xFF {
+ if PUT(emitter, b'x').fail {
+ return FAIL;
+ }
+ width = 2;
+ } else if value_0 <= 0xFFFF {
+ if PUT(emitter, b'u').fail {
+ return FAIL;
+ }
+ width = 4;
+ } else {
+ if PUT(emitter, b'U').fail {
+ return FAIL;
+ }
+ width = 8;
+ }
+ k = width.wrapping_sub(1).wrapping_mul(4) as libc::c_int;
+ while k >= 0 {
+ let digit: libc::c_int = (value_0 >> k & 0x0F) as libc::c_int;
+ if PUT(
+ emitter,
+ (digit + if digit < 10 { b'0' } else { b'A' - 10 } as i32) as u8,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ k -= 4;
+ }
+ }
+ }
+ spaces = false;
+ } else if IS_SPACE!(string) {
+ if allow_breaks
+ && !spaces
+ && (*emitter).column > (*emitter).best_width
+ && string.pointer != string.start
+ && string.pointer != string.end.wrapping_offset(-1_isize)
+ {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ if IS_SPACE_AT!(string, 1) {
+ if PUT(emitter, b'\\').fail {
+ return FAIL;
+ }
+ }
+ MOVE!(string);
+ } else if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ spaces = true;
+ } else {
+ if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ spaces = false;
+ }
+ }
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"\"\0" as *const u8 as *const libc::c_char,
+ false,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ (*emitter).whitespace = false;
+ (*emitter).indention = false;
+ OK
+}
+
+unsafe fn yaml_emitter_write_block_scalar_hints(
+ emitter: *mut yaml_emitter_t,
+ mut string: yaml_string_t,
+) -> Success {
+ let mut indent_hint: [libc::c_char; 2] = [0; 2];
+ let mut chomp_hint: *const libc::c_char = ptr::null::<libc::c_char>();
+ if IS_SPACE!(string) || IS_BREAK!(string) {
+ indent_hint[0] = (b'0' as libc::c_int + (*emitter).best_indent) as libc::c_char;
+ indent_hint[1] = '\0' as libc::c_char;
+ if yaml_emitter_write_indicator(emitter, indent_hint.as_mut_ptr(), false, false, false).fail
+ {
+ return FAIL;
+ }
+ }
+ (*emitter).open_ended = 0;
+ string.pointer = string.end;
+ if string.start == string.pointer {
+ chomp_hint = b"-\0" as *const u8 as *const libc::c_char;
+ } else {
+ loop {
+ string.pointer = string.pointer.wrapping_offset(-1);
+ if !(*string.pointer & 0xC0 == 0x80) {
+ break;
+ }
+ }
+ if !IS_BREAK!(string) {
+ chomp_hint = b"-\0" as *const u8 as *const libc::c_char;
+ } else if string.start == string.pointer {
+ chomp_hint = b"+\0" as *const u8 as *const libc::c_char;
+ (*emitter).open_ended = 2;
+ } else {
+ loop {
+ string.pointer = string.pointer.wrapping_offset(-1);
+ if !(*string.pointer & 0xC0 == 0x80) {
+ break;
+ }
+ }
+ if IS_BREAK!(string) {
+ chomp_hint = b"+\0" as *const u8 as *const libc::c_char;
+ (*emitter).open_ended = 2;
+ }
+ }
+ }
+ if !chomp_hint.is_null() {
+ if yaml_emitter_write_indicator(emitter, chomp_hint, false, false, false).fail {
+ return FAIL;
+ }
+ }
+ OK
+}
+
+unsafe fn yaml_emitter_write_literal_scalar(
+ emitter: *mut yaml_emitter_t,
+ value: *mut yaml_char_t,
+ length: size_t,
+) -> Success {
+ let mut breaks = true;
+ let mut string = STRING_ASSIGN!(value, length);
+ if yaml_emitter_write_indicator(
+ emitter,
+ b"|\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_block_scalar_hints(emitter, string).fail {
+ return FAIL;
+ }
+ if PUT_BREAK(emitter).fail {
+ return FAIL;
+ }
+ (*emitter).indention = true;
+ (*emitter).whitespace = true;
+ while string.pointer != string.end {
+ if IS_BREAK!(string) {
+ if WRITE_BREAK!(emitter, string).fail {
+ return FAIL;
+ }
+ (*emitter).indention = true;
+ breaks = true;
+ } else {
+ if breaks {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ }
+ if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ (*emitter).indention = false;
+ breaks = false;
+ }
+ }
+ OK
+}
+
+unsafe fn yaml_emitter_write_folded_scalar(
+ emitter: *mut yaml_emitter_t,
+ value: *mut yaml_char_t,
+ length: size_t,
+) -> Success {
+ let mut breaks = true;
+ let mut leading_spaces = true;
+ let mut string = STRING_ASSIGN!(value, length);
+ if yaml_emitter_write_indicator(
+ emitter,
+ b">\0" as *const u8 as *const libc::c_char,
+ true,
+ false,
+ false,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ if yaml_emitter_write_block_scalar_hints(emitter, string).fail {
+ return FAIL;
+ }
+ if PUT_BREAK(emitter).fail {
+ return FAIL;
+ }
+ (*emitter).indention = true;
+ (*emitter).whitespace = true;
+ while string.pointer != string.end {
+ if IS_BREAK!(string) {
+ if !breaks && !leading_spaces && CHECK!(string, b'\n') {
+ let mut k: libc::c_int = 0;
+ while IS_BREAK_AT!(string, k as isize) {
+ k += WIDTH_AT!(string, k as isize);
+ }
+ if !IS_BLANKZ_AT!(string, k) {
+ if PUT_BREAK(emitter).fail {
+ return FAIL;
+ }
+ }
+ }
+ if WRITE_BREAK!(emitter, string).fail {
+ return FAIL;
+ }
+ (*emitter).indention = true;
+ breaks = true;
+ } else {
+ if breaks {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ leading_spaces = IS_BLANK!(string);
+ }
+ if !breaks
+ && IS_SPACE!(string)
+ && !IS_SPACE_AT!(string, 1)
+ && (*emitter).column > (*emitter).best_width
+ {
+ if yaml_emitter_write_indent(emitter).fail {
+ return FAIL;
+ }
+ MOVE!(string);
+ } else if WRITE!(emitter, string).fail {
+ return FAIL;
+ }
+ (*emitter).indention = false;
+ breaks = false;
+ }
+ }
+ OK
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..aece24d
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,307 @@
+//! [![github]](https://github.com/dtolnay/unsafe-libyaml)&ensp;[![crates-io]](https://crates.io/crates/unsafe-libyaml)&ensp;[![docs-rs]](https://docs.rs/unsafe-libyaml)
+//!
+//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
+
+#![no_std]
+#![doc(html_root_url = "https://docs.rs/unsafe-libyaml/0.2.9")]
+#![allow(non_camel_case_types, non_snake_case)]
+#![warn(clippy::pedantic)]
+#![allow(
+ clippy::bool_to_int_with_if,
+ clippy::cast_lossless,
+ clippy::cast_possible_truncation,
+ clippy::cast_possible_wrap,
+ clippy::cast_ptr_alignment,
+ clippy::cast_sign_loss,
+ clippy::collapsible_if,
+ clippy::doc_markdown,
+ clippy::fn_params_excessive_bools,
+ clippy::if_not_else,
+ clippy::items_after_statements,
+ clippy::let_underscore_untyped,
+ clippy::manual_range_contains,
+ clippy::manual_swap,
+ clippy::missing_panics_doc,
+ clippy::missing_safety_doc,
+ clippy::module_name_repetitions,
+ clippy::must_use_candidate,
+ clippy::nonminimal_bool,
+ clippy::ptr_as_ptr,
+ clippy::redundant_else,
+ clippy::similar_names,
+ clippy::single_match,
+ clippy::single_match_else,
+ clippy::too_many_arguments,
+ clippy::too_many_lines,
+ clippy::unnecessary_cast,
+ clippy::unreadable_literal,
+ clippy::while_immutable_condition, // https://github.com/rust-lang/rust-clippy/issues/3548
+)]
+
+extern crate alloc;
+
+use core::mem::size_of;
+
+mod libc {
+ pub use core::ffi::c_void;
+ pub use core::primitive::{
+ i32 as c_int, i64 as c_long, i8 as c_char, i8 as c_schar, u16 as c_ushort, u32 as c_uint,
+ u64 as c_ulong, u8 as c_uchar,
+ };
+}
+
+#[macro_use]
+mod externs {
+ use crate::libc;
+ use alloc::alloc::{self as rust, Layout};
+ use core::mem::{self, MaybeUninit};
+ use core::ptr;
+ use core::slice;
+
+ const HEADER: usize = mem::size_of::<usize>();
+
+ // `max_align_t` may be bigger than this, but libyaml does not use `long
+ // double` or u128.
+ const MALLOC_ALIGN: usize = mem::align_of::<usize>();
+
+ pub unsafe fn malloc(size: libc::c_ulong) -> *mut libc::c_void {
+ let size = HEADER + size as usize;
+ let layout = Layout::from_size_align_unchecked(size, MALLOC_ALIGN);
+ let memory = rust::alloc(layout);
+ if memory.is_null() {
+ rust::handle_alloc_error(layout);
+ }
+ memory.cast::<usize>().write(size);
+ memory.add(HEADER).cast()
+ }
+
+ pub unsafe fn realloc(ptr: *mut libc::c_void, new_size: libc::c_ulong) -> *mut libc::c_void {
+ let mut memory = ptr.cast::<u8>().sub(HEADER);
+ let size = memory.cast::<usize>().read();
+ let layout = Layout::from_size_align_unchecked(size, MALLOC_ALIGN);
+ let new_size = HEADER + new_size as usize;
+ memory = rust::realloc(memory, layout, new_size);
+ if memory.is_null() {
+ let layout = Layout::from_size_align_unchecked(new_size, MALLOC_ALIGN);
+ rust::handle_alloc_error(layout);
+ }
+ memory.cast::<usize>().write(new_size);
+ memory.add(HEADER).cast()
+ }
+
+ pub unsafe fn free(ptr: *mut libc::c_void) {
+ let memory = ptr.cast::<u8>().sub(HEADER);
+ let size = memory.cast::<usize>().read();
+ let layout = Layout::from_size_align_unchecked(size, MALLOC_ALIGN);
+ rust::dealloc(memory, layout);
+ }
+
+ pub unsafe fn memcmp(
+ lhs: *const libc::c_void,
+ rhs: *const libc::c_void,
+ count: libc::c_ulong,
+ ) -> libc::c_int {
+ let lhs = slice::from_raw_parts(lhs.cast::<u8>(), count as usize);
+ let rhs = slice::from_raw_parts(rhs.cast::<u8>(), count as usize);
+ lhs.cmp(rhs) as libc::c_int
+ }
+
+ pub unsafe fn memcpy(
+ dest: *mut libc::c_void,
+ src: *const libc::c_void,
+ count: libc::c_ulong,
+ ) -> *mut libc::c_void {
+ ptr::copy_nonoverlapping(
+ src.cast::<MaybeUninit<u8>>(),
+ dest.cast::<MaybeUninit<u8>>(),
+ count as usize,
+ );
+ dest
+ }
+
+ pub unsafe fn memmove(
+ dest: *mut libc::c_void,
+ src: *const libc::c_void,
+ count: libc::c_ulong,
+ ) -> *mut libc::c_void {
+ ptr::copy(
+ src.cast::<MaybeUninit<u8>>(),
+ dest.cast::<MaybeUninit<u8>>(),
+ count as usize,
+ );
+ dest
+ }
+
+ pub unsafe fn memset(
+ dest: *mut libc::c_void,
+ ch: libc::c_int,
+ count: libc::c_ulong,
+ ) -> *mut libc::c_void {
+ ptr::write_bytes(dest.cast::<u8>(), ch as u8, count as usize);
+ dest
+ }
+
+ pub unsafe fn strcmp(lhs: *const libc::c_char, rhs: *const libc::c_char) -> libc::c_int {
+ let lhs = slice::from_raw_parts(lhs.cast::<u8>(), strlen(lhs) as usize);
+ let rhs = slice::from_raw_parts(rhs.cast::<u8>(), strlen(rhs) as usize);
+ lhs.cmp(rhs) as libc::c_int
+ }
+
+ pub unsafe fn strdup(src: *const libc::c_char) -> *mut libc::c_char {
+ let len = strlen(src);
+ let dest = malloc(len + 1);
+ memcpy(dest, src.cast(), len + 1);
+ dest.cast()
+ }
+
+ pub unsafe fn strlen(str: *const libc::c_char) -> libc::c_ulong {
+ let mut end = str;
+ while *end != 0 {
+ end = end.add(1);
+ }
+ end.offset_from(str) as libc::c_ulong
+ }
+
+ pub unsafe fn strncmp(
+ lhs: *const libc::c_char,
+ rhs: *const libc::c_char,
+ mut count: libc::c_ulong,
+ ) -> libc::c_int {
+ let mut lhs = lhs.cast::<u8>();
+ let mut rhs = rhs.cast::<u8>();
+ while count > 0 && *lhs != 0 && *lhs == *rhs {
+ lhs = lhs.add(1);
+ rhs = rhs.add(1);
+ count -= 1;
+ }
+ if count == 0 {
+ 0
+ } else {
+ (*lhs).cmp(&*rhs) as libc::c_int
+ }
+ }
+
+ macro_rules! __assert {
+ (false $(,)?) => {
+ $crate::externs::__assert_fail(stringify!(false), file!(), line!())
+ };
+ ($assertion:expr $(,)?) => {
+ if !$assertion {
+ $crate::externs::__assert_fail(stringify!($assertion), file!(), line!());
+ }
+ };
+ }
+
+ pub(crate) unsafe fn __assert_fail(
+ __assertion: &'static str,
+ __file: &'static str,
+ __line: u32,
+ ) -> ! {
+ struct Abort;
+ impl Drop for Abort {
+ fn drop(&mut self) {
+ panic!();
+ }
+ }
+ let _abort_on_panic = Abort;
+ panic!("{}:{}: Assertion `{}` failed.", __file, __line, __assertion);
+ }
+}
+
+mod fmt {
+ use crate::yaml::yaml_char_t;
+ use core::fmt::{self, Write};
+ use core::ptr;
+
+ pub struct WriteToPtr {
+ ptr: *mut yaml_char_t,
+ }
+
+ impl WriteToPtr {
+ pub unsafe fn new(ptr: *mut yaml_char_t) -> Self {
+ WriteToPtr { ptr }
+ }
+
+ pub fn write_fmt(&mut self, args: fmt::Arguments) {
+ let _ = Write::write_fmt(self, args);
+ }
+ }
+
+ impl Write for WriteToPtr {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ unsafe {
+ ptr::copy_nonoverlapping(s.as_ptr(), self.ptr, s.len());
+ self.ptr = self.ptr.add(s.len());
+ }
+ Ok(())
+ }
+ }
+}
+
+trait PointerExt: Sized {
+ fn c_offset_from(self, origin: Self) -> isize;
+}
+
+impl<T> PointerExt for *const T {
+ fn c_offset_from(self, origin: *const T) -> isize {
+ (self as isize - origin as isize) / size_of::<T>() as isize
+ }
+}
+
+impl<T> PointerExt for *mut T {
+ fn c_offset_from(self, origin: *mut T) -> isize {
+ (self as isize - origin as isize) / size_of::<T>() as isize
+ }
+}
+
+#[macro_use]
+mod macros;
+
+mod api;
+mod dumper;
+mod emitter;
+mod loader;
+mod parser;
+mod reader;
+mod scanner;
+mod success;
+mod writer;
+mod yaml;
+
+pub use crate::api::{
+ yaml_alias_event_initialize, yaml_document_add_mapping, yaml_document_add_scalar,
+ yaml_document_add_sequence, yaml_document_append_mapping_pair,
+ yaml_document_append_sequence_item, yaml_document_delete, yaml_document_end_event_initialize,
+ yaml_document_get_node, yaml_document_get_root_node, yaml_document_initialize,
+ yaml_document_start_event_initialize, yaml_emitter_delete, yaml_emitter_initialize,
+ yaml_emitter_set_break, yaml_emitter_set_canonical, yaml_emitter_set_encoding,
+ yaml_emitter_set_indent, yaml_emitter_set_output, yaml_emitter_set_output_string,
+ yaml_emitter_set_unicode, yaml_emitter_set_width, yaml_event_delete,
+ yaml_mapping_end_event_initialize, yaml_mapping_start_event_initialize, yaml_parser_delete,
+ yaml_parser_initialize, yaml_parser_set_encoding, yaml_parser_set_input,
+ yaml_parser_set_input_string, yaml_scalar_event_initialize, yaml_sequence_end_event_initialize,
+ yaml_sequence_start_event_initialize, yaml_stream_end_event_initialize,
+ yaml_stream_start_event_initialize, yaml_token_delete,
+};
+pub use crate::dumper::{yaml_emitter_close, yaml_emitter_dump, yaml_emitter_open};
+pub use crate::emitter::yaml_emitter_emit;
+pub use crate::loader::yaml_parser_load;
+pub use crate::parser::yaml_parser_parse;
+pub use crate::scanner::yaml_parser_scan;
+pub use crate::writer::yaml_emitter_flush;
+pub use crate::yaml::{
+ yaml_alias_data_t, yaml_break_t, yaml_document_t, yaml_emitter_state_t, yaml_emitter_t,
+ yaml_encoding_t, yaml_error_type_t, yaml_event_t, yaml_event_type_t, yaml_mapping_style_t,
+ yaml_mark_t, yaml_node_item_t, yaml_node_pair_t, yaml_node_t, yaml_node_type_t,
+ yaml_parser_state_t, yaml_parser_t, yaml_read_handler_t, yaml_scalar_style_t,
+ yaml_sequence_style_t, yaml_simple_key_t, yaml_stack_t, yaml_tag_directive_t, yaml_token_t,
+ yaml_token_type_t, yaml_version_directive_t, yaml_write_handler_t,
+};
+#[doc(hidden)]
+pub use crate::yaml::{
+ yaml_break_t::*, yaml_emitter_state_t::*, yaml_encoding_t::*, yaml_error_type_t::*,
+ yaml_event_type_t::*, yaml_mapping_style_t::*, yaml_node_type_t::*, yaml_parser_state_t::*,
+ yaml_scalar_style_t::*, yaml_sequence_style_t::*, yaml_token_type_t::*,
+};
diff --git a/src/loader.rs b/src/loader.rs
new file mode 100644
index 0000000..6d562c0
--- /dev/null
+++ b/src/loader.rs
@@ -0,0 +1,579 @@
+use crate::api::{yaml_free, yaml_malloc, yaml_stack_extend, yaml_strdup};
+use crate::externs::{memset, strcmp};
+use crate::success::{Success, FAIL, OK};
+use crate::yaml::yaml_char_t;
+use crate::{
+ libc, yaml_alias_data_t, yaml_document_delete, yaml_document_t, yaml_event_t, yaml_mark_t,
+ yaml_node_item_t, yaml_node_pair_t, yaml_node_t, yaml_parser_parse, yaml_parser_t, PointerExt,
+ YAML_ALIAS_EVENT, YAML_COMPOSER_ERROR, YAML_DOCUMENT_END_EVENT, YAML_DOCUMENT_START_EVENT,
+ YAML_MAPPING_END_EVENT, YAML_MAPPING_NODE, YAML_MAPPING_START_EVENT, YAML_MEMORY_ERROR,
+ YAML_SCALAR_EVENT, YAML_SCALAR_NODE, YAML_SEQUENCE_END_EVENT, YAML_SEQUENCE_NODE,
+ YAML_SEQUENCE_START_EVENT, YAML_STREAM_END_EVENT, YAML_STREAM_START_EVENT,
+};
+use core::mem::{size_of, MaybeUninit};
+use core::ptr::{self, addr_of_mut};
+
+#[repr(C)]
+struct loader_ctx {
+ start: *mut libc::c_int,
+ end: *mut libc::c_int,
+ top: *mut libc::c_int,
+}
+
+/// Parse the input stream and produce the next YAML document.
+///
+/// Call this function subsequently to produce a sequence of documents
+/// constituting the input stream.
+///
+/// If the produced document has no root node, it means that the document end
+/// has been reached.
+///
+/// An application is responsible for freeing any data associated with the
+/// produced document object using the yaml_document_delete() function.
+///
+/// An application must not alternate the calls of yaml_parser_load() with the
+/// calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break
+/// the parser.
+pub unsafe fn yaml_parser_load(
+ parser: *mut yaml_parser_t,
+ document: *mut yaml_document_t,
+) -> Success {
+ let current_block: u64;
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ __assert!(!parser.is_null());
+ __assert!(!document.is_null());
+ memset(
+ document as *mut libc::c_void,
+ 0,
+ size_of::<yaml_document_t>() as libc::c_ulong,
+ );
+ STACK_INIT!((*document).nodes, yaml_node_t);
+ if !(*parser).stream_start_produced {
+ if yaml_parser_parse(parser, event).fail {
+ current_block = 6234624449317607669;
+ } else {
+ __assert!((*event).type_ == YAML_STREAM_START_EVENT);
+ current_block = 7815301370352969686;
+ }
+ } else {
+ current_block = 7815301370352969686;
+ }
+ if current_block != 6234624449317607669 {
+ if (*parser).stream_end_produced {
+ return OK;
+ }
+ if yaml_parser_parse(parser, event).ok {
+ if (*event).type_ == YAML_STREAM_END_EVENT {
+ return OK;
+ }
+ STACK_INIT!((*parser).aliases, yaml_alias_data_t);
+ let fresh6 = addr_of_mut!((*parser).document);
+ *fresh6 = document;
+ if yaml_parser_load_document(parser, event).ok {
+ yaml_parser_delete_aliases(parser);
+ let fresh7 = addr_of_mut!((*parser).document);
+ *fresh7 = ptr::null_mut::<yaml_document_t>();
+ return OK;
+ }
+ }
+ }
+ yaml_parser_delete_aliases(parser);
+ yaml_document_delete(document);
+ let fresh8 = addr_of_mut!((*parser).document);
+ *fresh8 = ptr::null_mut::<yaml_document_t>();
+ FAIL
+}
+
+unsafe fn yaml_parser_set_composer_error(
+ parser: *mut yaml_parser_t,
+ problem: *const libc::c_char,
+ problem_mark: yaml_mark_t,
+) -> Success {
+ (*parser).error = YAML_COMPOSER_ERROR;
+ let fresh9 = addr_of_mut!((*parser).problem);
+ *fresh9 = problem;
+ (*parser).problem_mark = problem_mark;
+ FAIL
+}
+
+unsafe fn yaml_parser_set_composer_error_context(
+ parser: *mut yaml_parser_t,
+ context: *const libc::c_char,
+ context_mark: yaml_mark_t,
+ problem: *const libc::c_char,
+ problem_mark: yaml_mark_t,
+) -> Success {
+ (*parser).error = YAML_COMPOSER_ERROR;
+ let fresh10 = addr_of_mut!((*parser).context);
+ *fresh10 = context;
+ (*parser).context_mark = context_mark;
+ let fresh11 = addr_of_mut!((*parser).problem);
+ *fresh11 = problem;
+ (*parser).problem_mark = problem_mark;
+ FAIL
+}
+
+unsafe fn yaml_parser_delete_aliases(parser: *mut yaml_parser_t) {
+ while !STACK_EMPTY!((*parser).aliases) {
+ yaml_free(POP!((*parser).aliases).anchor as *mut libc::c_void);
+ }
+ STACK_DEL!((*parser).aliases);
+}
+
+unsafe fn yaml_parser_load_document(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let mut ctx = loader_ctx {
+ start: ptr::null_mut::<libc::c_int>(),
+ end: ptr::null_mut::<libc::c_int>(),
+ top: ptr::null_mut::<libc::c_int>(),
+ };
+ __assert!((*event).type_ == YAML_DOCUMENT_START_EVENT);
+ let fresh16 = addr_of_mut!((*(*parser).document).version_directive);
+ *fresh16 = (*event).data.document_start.version_directive;
+ let fresh17 = addr_of_mut!((*(*parser).document).tag_directives.start);
+ *fresh17 = (*event).data.document_start.tag_directives.start;
+ let fresh18 = addr_of_mut!((*(*parser).document).tag_directives.end);
+ *fresh18 = (*event).data.document_start.tag_directives.end;
+ (*(*parser).document).start_implicit = (*event).data.document_start.implicit;
+ (*(*parser).document).start_mark = (*event).start_mark;
+ STACK_INIT!(ctx, libc::c_int);
+ if yaml_parser_load_nodes(parser, addr_of_mut!(ctx)).fail {
+ STACK_DEL!(ctx);
+ return FAIL;
+ }
+ STACK_DEL!(ctx);
+ OK
+}
+
+unsafe fn yaml_parser_load_nodes(parser: *mut yaml_parser_t, ctx: *mut loader_ctx) -> Success {
+ let mut event = MaybeUninit::<yaml_event_t>::uninit();
+ let event = event.as_mut_ptr();
+ loop {
+ if yaml_parser_parse(parser, event).fail {
+ return FAIL;
+ }
+ match (*event).type_ {
+ YAML_ALIAS_EVENT => {
+ if yaml_parser_load_alias(parser, event, ctx).fail {
+ return FAIL;
+ }
+ }
+ YAML_SCALAR_EVENT => {
+ if yaml_parser_load_scalar(parser, event, ctx).fail {
+ return FAIL;
+ }
+ }
+ YAML_SEQUENCE_START_EVENT => {
+ if yaml_parser_load_sequence(parser, event, ctx).fail {
+ return FAIL;
+ }
+ }
+ YAML_SEQUENCE_END_EVENT => {
+ if yaml_parser_load_sequence_end(parser, event, ctx).fail {
+ return FAIL;
+ }
+ }
+ YAML_MAPPING_START_EVENT => {
+ if yaml_parser_load_mapping(parser, event, ctx).fail {
+ return FAIL;
+ }
+ }
+ YAML_MAPPING_END_EVENT => {
+ if yaml_parser_load_mapping_end(parser, event, ctx).fail {
+ return FAIL;
+ }
+ }
+ YAML_DOCUMENT_END_EVENT => {}
+ _ => {
+ __assert!(false);
+ }
+ }
+ if (*event).type_ == YAML_DOCUMENT_END_EVENT {
+ break;
+ }
+ }
+ (*(*parser).document).end_implicit = (*event).data.document_end.implicit;
+ (*(*parser).document).end_mark = (*event).end_mark;
+ OK
+}
+
+unsafe fn yaml_parser_register_anchor(
+ parser: *mut yaml_parser_t,
+ index: libc::c_int,
+ anchor: *mut yaml_char_t,
+) -> Success {
+ let mut data = MaybeUninit::<yaml_alias_data_t>::uninit();
+ let data = data.as_mut_ptr();
+ let mut alias_data: *mut yaml_alias_data_t;
+ if anchor.is_null() {
+ return OK;
+ }
+ (*data).anchor = anchor;
+ (*data).index = index;
+ (*data).mark = (*(*(*parser).document)
+ .nodes
+ .start
+ .wrapping_offset((index - 1) as isize))
+ .start_mark;
+ alias_data = (*parser).aliases.start;
+ while alias_data != (*parser).aliases.top {
+ if strcmp(
+ (*alias_data).anchor as *mut libc::c_char,
+ anchor as *mut libc::c_char,
+ ) == 0
+ {
+ yaml_free(anchor as *mut libc::c_void);
+ return yaml_parser_set_composer_error_context(
+ parser,
+ b"found duplicate anchor; first occurrence\0" as *const u8 as *const libc::c_char,
+ (*alias_data).mark,
+ b"second occurrence\0" as *const u8 as *const libc::c_char,
+ (*data).mark,
+ );
+ }
+ alias_data = alias_data.wrapping_offset(1);
+ }
+ PUSH!((*parser).aliases, *data);
+ OK
+}
+
+unsafe fn yaml_parser_load_node_add(
+ parser: *mut yaml_parser_t,
+ ctx: *mut loader_ctx,
+ index: libc::c_int,
+) -> Success {
+ if STACK_EMPTY!(*ctx) {
+ return OK;
+ }
+ let parent_index: libc::c_int = *(*ctx).top.wrapping_offset(-1_isize);
+ let parent: *mut yaml_node_t = addr_of_mut!(
+ *((*(*parser).document).nodes.start).wrapping_offset((parent_index - 1) as isize)
+ );
+ let current_block_17: u64;
+ match (*parent).type_ {
+ YAML_SEQUENCE_NODE => {
+ if STACK_LIMIT!(parser, (*parent).data.sequence.items).fail {
+ return FAIL;
+ }
+ PUSH!((*parent).data.sequence.items, index);
+ }
+ YAML_MAPPING_NODE => {
+ let mut pair = MaybeUninit::<yaml_node_pair_t>::uninit();
+ let pair = pair.as_mut_ptr();
+ if !STACK_EMPTY!((*parent).data.mapping.pairs) {
+ let p: *mut yaml_node_pair_t =
+ (*parent).data.mapping.pairs.top.wrapping_offset(-1_isize);
+ if (*p).key != 0 && (*p).value == 0 {
+ (*p).value = index;
+ current_block_17 = 11307063007268554308;
+ } else {
+ current_block_17 = 17407779659766490442;
+ }
+ } else {
+ current_block_17 = 17407779659766490442;
+ }
+ match current_block_17 {
+ 11307063007268554308 => {}
+ _ => {
+ (*pair).key = index;
+ (*pair).value = 0;
+ if STACK_LIMIT!(parser, (*parent).data.mapping.pairs).fail {
+ return FAIL;
+ }
+ PUSH!((*parent).data.mapping.pairs, *pair);
+ }
+ }
+ }
+ _ => {
+ __assert!(false);
+ }
+ }
+ OK
+}
+
+unsafe fn yaml_parser_load_alias(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ ctx: *mut loader_ctx,
+) -> Success {
+ let anchor: *mut yaml_char_t = (*event).data.alias.anchor;
+ let mut alias_data: *mut yaml_alias_data_t;
+ alias_data = (*parser).aliases.start;
+ while alias_data != (*parser).aliases.top {
+ if strcmp(
+ (*alias_data).anchor as *mut libc::c_char,
+ anchor as *mut libc::c_char,
+ ) == 0
+ {
+ yaml_free(anchor as *mut libc::c_void);
+ return yaml_parser_load_node_add(parser, ctx, (*alias_data).index);
+ }
+ alias_data = alias_data.wrapping_offset(1);
+ }
+ yaml_free(anchor as *mut libc::c_void);
+ yaml_parser_set_composer_error(
+ parser,
+ b"found undefined alias\0" as *const u8 as *const libc::c_char,
+ (*event).start_mark,
+ )
+}
+
+unsafe fn yaml_parser_load_scalar(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ ctx: *mut loader_ctx,
+) -> Success {
+ let current_block: u64;
+ let mut node = MaybeUninit::<yaml_node_t>::uninit();
+ let node = node.as_mut_ptr();
+ let index: libc::c_int;
+ let mut tag: *mut yaml_char_t = (*event).data.scalar.tag;
+ if STACK_LIMIT!(parser, (*(*parser).document).nodes).ok {
+ if tag.is_null()
+ || strcmp(
+ tag as *mut libc::c_char,
+ b"!\0" as *const u8 as *const libc::c_char,
+ ) == 0
+ {
+ yaml_free(tag as *mut libc::c_void);
+ tag = yaml_strdup(
+ b"tag:yaml.org,2002:str\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
+ );
+ if tag.is_null() {
+ current_block = 10579931339944277179;
+ } else {
+ current_block = 11006700562992250127;
+ }
+ } else {
+ current_block = 11006700562992250127;
+ }
+ if current_block != 10579931339944277179 {
+ memset(
+ node as *mut libc::c_void,
+ 0,
+ size_of::<yaml_node_t>() as libc::c_ulong,
+ );
+ (*node).type_ = YAML_SCALAR_NODE;
+ (*node).tag = tag;
+ (*node).start_mark = (*event).start_mark;
+ (*node).end_mark = (*event).end_mark;
+ (*node).data.scalar.value = (*event).data.scalar.value;
+ (*node).data.scalar.length = (*event).data.scalar.length;
+ (*node).data.scalar.style = (*event).data.scalar.style;
+ PUSH!((*(*parser).document).nodes, *node);
+ index = (*(*parser).document)
+ .nodes
+ .top
+ .c_offset_from((*(*parser).document).nodes.start)
+ as libc::c_int;
+ if yaml_parser_register_anchor(parser, index, (*event).data.scalar.anchor).fail {
+ return FAIL;
+ }
+ return yaml_parser_load_node_add(parser, ctx, index);
+ }
+ }
+ yaml_free(tag as *mut libc::c_void);
+ yaml_free((*event).data.scalar.anchor as *mut libc::c_void);
+ yaml_free((*event).data.scalar.value as *mut libc::c_void);
+ FAIL
+}
+
+unsafe fn yaml_parser_load_sequence(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ ctx: *mut loader_ctx,
+) -> Success {
+ let current_block: u64;
+ let mut node = MaybeUninit::<yaml_node_t>::uninit();
+ let node = node.as_mut_ptr();
+ struct Items {
+ start: *mut yaml_node_item_t,
+ end: *mut yaml_node_item_t,
+ top: *mut yaml_node_item_t,
+ }
+ let mut items = Items {
+ start: ptr::null_mut::<yaml_node_item_t>(),
+ end: ptr::null_mut::<yaml_node_item_t>(),
+ top: ptr::null_mut::<yaml_node_item_t>(),
+ };
+ let index: libc::c_int;
+ let mut tag: *mut yaml_char_t = (*event).data.sequence_start.tag;
+ if STACK_LIMIT!(parser, (*(*parser).document).nodes).ok {
+ if tag.is_null()
+ || strcmp(
+ tag as *mut libc::c_char,
+ b"!\0" as *const u8 as *const libc::c_char,
+ ) == 0
+ {
+ yaml_free(tag as *mut libc::c_void);
+ tag = yaml_strdup(
+ b"tag:yaml.org,2002:seq\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
+ );
+ if tag.is_null() {
+ current_block = 13474536459355229096;
+ } else {
+ current_block = 6937071982253665452;
+ }
+ } else {
+ current_block = 6937071982253665452;
+ }
+ if current_block != 13474536459355229096 {
+ STACK_INIT!(items, yaml_node_item_t);
+ memset(
+ node as *mut libc::c_void,
+ 0,
+ size_of::<yaml_node_t>() as libc::c_ulong,
+ );
+ (*node).type_ = YAML_SEQUENCE_NODE;
+ (*node).tag = tag;
+ (*node).start_mark = (*event).start_mark;
+ (*node).end_mark = (*event).end_mark;
+ (*node).data.sequence.items.start = items.start;
+ (*node).data.sequence.items.end = items.end;
+ (*node).data.sequence.items.top = items.start;
+ (*node).data.sequence.style = (*event).data.sequence_start.style;
+ PUSH!((*(*parser).document).nodes, *node);
+ index = (*(*parser).document)
+ .nodes
+ .top
+ .c_offset_from((*(*parser).document).nodes.start)
+ as libc::c_int;
+ if yaml_parser_register_anchor(parser, index, (*event).data.sequence_start.anchor).fail
+ {
+ return FAIL;
+ }
+ if yaml_parser_load_node_add(parser, ctx, index).fail {
+ return FAIL;
+ }
+ if STACK_LIMIT!(parser, *ctx).fail {
+ return FAIL;
+ }
+ PUSH!(*ctx, index);
+ return OK;
+ }
+ }
+ yaml_free(tag as *mut libc::c_void);
+ yaml_free((*event).data.sequence_start.anchor as *mut libc::c_void);
+ FAIL
+}
+
+unsafe fn yaml_parser_load_sequence_end(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ ctx: *mut loader_ctx,
+) -> Success {
+ __assert!(((*ctx).top).c_offset_from((*ctx).start) as libc::c_long > 0_i64);
+ let index: libc::c_int = *(*ctx).top.wrapping_offset(-1_isize);
+ __assert!(
+ (*((*(*parser).document).nodes.start).wrapping_offset((index - 1) as isize)).type_
+ == YAML_SEQUENCE_NODE
+ );
+ (*(*(*parser).document)
+ .nodes
+ .start
+ .wrapping_offset((index - 1) as isize))
+ .end_mark = (*event).end_mark;
+ let _ = POP!(*ctx);
+ OK
+}
+
+unsafe fn yaml_parser_load_mapping(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ ctx: *mut loader_ctx,
+) -> Success {
+ let current_block: u64;
+ let mut node = MaybeUninit::<yaml_node_t>::uninit();
+ let node = node.as_mut_ptr();
+ struct Pairs {
+ start: *mut yaml_node_pair_t,
+ end: *mut yaml_node_pair_t,
+ top: *mut yaml_node_pair_t,
+ }
+ let mut pairs = Pairs {
+ start: ptr::null_mut::<yaml_node_pair_t>(),
+ end: ptr::null_mut::<yaml_node_pair_t>(),
+ top: ptr::null_mut::<yaml_node_pair_t>(),
+ };
+ let index: libc::c_int;
+ let mut tag: *mut yaml_char_t = (*event).data.mapping_start.tag;
+ if STACK_LIMIT!(parser, (*(*parser).document).nodes).ok {
+ if tag.is_null()
+ || strcmp(
+ tag as *mut libc::c_char,
+ b"!\0" as *const u8 as *const libc::c_char,
+ ) == 0
+ {
+ yaml_free(tag as *mut libc::c_void);
+ tag = yaml_strdup(
+ b"tag:yaml.org,2002:map\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
+ );
+ if tag.is_null() {
+ current_block = 13635467803606088781;
+ } else {
+ current_block = 6937071982253665452;
+ }
+ } else {
+ current_block = 6937071982253665452;
+ }
+ if current_block != 13635467803606088781 {
+ STACK_INIT!(pairs, yaml_node_pair_t);
+ memset(
+ node as *mut libc::c_void,
+ 0,
+ size_of::<yaml_node_t>() as libc::c_ulong,
+ );
+ (*node).type_ = YAML_MAPPING_NODE;
+ (*node).tag = tag;
+ (*node).start_mark = (*event).start_mark;
+ (*node).end_mark = (*event).end_mark;
+ (*node).data.mapping.pairs.start = pairs.start;
+ (*node).data.mapping.pairs.end = pairs.end;
+ (*node).data.mapping.pairs.top = pairs.start;
+ (*node).data.mapping.style = (*event).data.mapping_start.style;
+ PUSH!((*(*parser).document).nodes, *node);
+ index = (*(*parser).document)
+ .nodes
+ .top
+ .c_offset_from((*(*parser).document).nodes.start)
+ as libc::c_int;
+ if yaml_parser_register_anchor(parser, index, (*event).data.mapping_start.anchor).fail {
+ return FAIL;
+ }
+ if yaml_parser_load_node_add(parser, ctx, index).fail {
+ return FAIL;
+ }
+ if STACK_LIMIT!(parser, *ctx).fail {
+ return FAIL;
+ }
+ PUSH!(*ctx, index);
+ return OK;
+ }
+ }
+ yaml_free(tag as *mut libc::c_void);
+ yaml_free((*event).data.mapping_start.anchor as *mut libc::c_void);
+ FAIL
+}
+
+unsafe fn yaml_parser_load_mapping_end(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ ctx: *mut loader_ctx,
+) -> Success {
+ __assert!(((*ctx).top).c_offset_from((*ctx).start) as libc::c_long > 0_i64);
+ let index: libc::c_int = *(*ctx).top.wrapping_offset(-1_isize);
+ __assert!(
+ (*((*(*parser).document).nodes.start).wrapping_offset((index - 1) as isize)).type_
+ == YAML_MAPPING_NODE
+ );
+ (*(*(*parser).document)
+ .nodes
+ .start
+ .wrapping_offset((index - 1) as isize))
+ .end_mark = (*event).end_mark;
+ let _ = POP!(*ctx);
+ OK
+}
diff --git a/src/macros.rs b/src/macros.rs
new file mode 100644
index 0000000..9668929
--- /dev/null
+++ b/src/macros.rs
@@ -0,0 +1,514 @@
+macro_rules! BUFFER_INIT {
+ ($buffer:expr, $size:expr) => {{
+ let start = addr_of_mut!($buffer.start);
+ *start = yaml_malloc($size as size_t) as *mut yaml_char_t;
+ let pointer = addr_of_mut!($buffer.pointer);
+ *pointer = $buffer.start;
+ let last = addr_of_mut!($buffer.last);
+ *last = *pointer;
+ let end = addr_of_mut!($buffer.end);
+ *end = $buffer.start.wrapping_add($size as usize);
+ }};
+}
+
+macro_rules! BUFFER_DEL {
+ ($buffer:expr) => {{
+ yaml_free($buffer.start as *mut libc::c_void);
+ let end = addr_of_mut!($buffer.end);
+ *end = ptr::null_mut::<yaml_char_t>();
+ let pointer = addr_of_mut!($buffer.pointer);
+ *pointer = *end;
+ let start = addr_of_mut!($buffer.start);
+ *start = *pointer;
+ }};
+}
+
+macro_rules! STRING_ASSIGN {
+ ($string:expr, $length:expr) => {
+ yaml_string_t {
+ start: $string,
+ end: $string.wrapping_offset($length as isize),
+ pointer: $string,
+ }
+ };
+}
+
+macro_rules! STRING_INIT {
+ ($string:expr) => {{
+ $string.start = yaml_malloc(16) as *mut yaml_char_t;
+ $string.pointer = $string.start;
+ $string.end = $string.start.wrapping_add(16);
+ memset($string.start as *mut libc::c_void, 0, 16);
+ }};
+}
+
+macro_rules! STRING_DEL {
+ ($string:expr) => {{
+ yaml_free($string.start as *mut libc::c_void);
+ $string.end = ptr::null_mut::<yaml_char_t>();
+ $string.pointer = $string.end;
+ $string.start = $string.pointer;
+ }};
+}
+
+macro_rules! STRING_EXTEND {
+ ($string:expr) => {
+ if $string.pointer.wrapping_add(5) >= $string.end {
+ yaml_string_extend(
+ addr_of_mut!($string.start),
+ addr_of_mut!($string.pointer),
+ addr_of_mut!($string.end),
+ );
+ }
+ };
+}
+
+macro_rules! CLEAR {
+ ($string:expr) => {{
+ $string.pointer = $string.start;
+ memset(
+ $string.start as *mut libc::c_void,
+ 0,
+ $string.end.c_offset_from($string.start) as libc::c_ulong,
+ );
+ }};
+}
+
+macro_rules! JOIN {
+ ($string_a:expr, $string_b:expr) => {{
+ yaml_string_join(
+ addr_of_mut!($string_a.start),
+ addr_of_mut!($string_a.pointer),
+ addr_of_mut!($string_a.end),
+ addr_of_mut!($string_b.start),
+ addr_of_mut!($string_b.pointer),
+ addr_of_mut!($string_b.end),
+ );
+ $string_b.pointer = $string_b.start;
+ }};
+}
+
+macro_rules! CHECK_AT {
+ ($string:expr, $octet:expr, $offset:expr) => {
+ *$string.pointer.offset($offset as isize) == $octet
+ };
+}
+
+macro_rules! CHECK {
+ ($string:expr, $octet:expr) => {
+ *$string.pointer == $octet
+ };
+}
+
+macro_rules! IS_ALPHA {
+ ($string:expr) => {
+ *$string.pointer >= b'0' && *$string.pointer <= b'9'
+ || *$string.pointer >= b'A' && *$string.pointer <= b'Z'
+ || *$string.pointer >= b'a' && *$string.pointer <= b'z'
+ || *$string.pointer == b'_'
+ || *$string.pointer == b'-'
+ };
+}
+
+macro_rules! IS_DIGIT {
+ ($string:expr) => {
+ *$string.pointer >= b'0' && *$string.pointer <= b'9'
+ };
+}
+
+macro_rules! AS_DIGIT {
+ ($string:expr) => {
+ (*$string.pointer - b'0') as libc::c_int
+ };
+}
+
+macro_rules! IS_HEX_AT {
+ ($string:expr, $offset:expr) => {
+ *$string.pointer.wrapping_offset($offset) >= b'0'
+ && *$string.pointer.wrapping_offset($offset) <= b'9'
+ || *$string.pointer.wrapping_offset($offset) >= b'A'
+ && *$string.pointer.wrapping_offset($offset) <= b'F'
+ || *$string.pointer.wrapping_offset($offset) >= b'a'
+ && *$string.pointer.wrapping_offset($offset) <= b'f'
+ };
+}
+
+macro_rules! AS_HEX_AT {
+ ($string:expr, $offset:expr) => {
+ if *$string.pointer.wrapping_offset($offset) >= b'A'
+ && *$string.pointer.wrapping_offset($offset) <= b'F'
+ {
+ *$string.pointer.wrapping_offset($offset) - b'A' + 10
+ } else if *$string.pointer.wrapping_offset($offset) >= b'a'
+ && *$string.pointer.wrapping_offset($offset) <= b'f'
+ {
+ *$string.pointer.wrapping_offset($offset) - b'a' + 10
+ } else {
+ *$string.pointer.wrapping_offset($offset) - b'0'
+ } as libc::c_int
+ };
+}
+
+macro_rules! IS_ASCII {
+ ($string:expr) => {
+ *$string.pointer <= b'\x7F'
+ };
+}
+
+macro_rules! IS_PRINTABLE {
+ ($string:expr) => {
+ match *$string.pointer {
+ // ASCII
+ 0x0A | 0x20..=0x7E => true,
+ // U+A0 ... U+BF
+ 0xC2 => match *$string.pointer.wrapping_offset(1) {
+ 0xA0..=0xBF => true,
+ _ => false,
+ },
+ // U+C0 ... U+CFFF
+ 0xC3..=0xEC => true,
+ // U+D000 ... U+D7FF
+ 0xED => match *$string.pointer.wrapping_offset(1) {
+ 0x00..=0x9F => true,
+ _ => false,
+ },
+ // U+E000 ... U+EFFF
+ 0xEE => true,
+ // U+F000 ... U+FFFD
+ 0xEF => match *$string.pointer.wrapping_offset(1) {
+ 0xBB => match *$string.pointer.wrapping_offset(2) {
+ // except U+FEFF
+ 0xBF => false,
+ _ => true,
+ },
+ 0xBF => match *$string.pointer.wrapping_offset(2) {
+ 0xBE | 0xBF => false,
+ _ => true,
+ },
+ _ => true,
+ },
+ // U+10000 ... U+10FFFF
+ 0xF0..=0xF4 => true,
+ _ => false,
+ }
+ };
+}
+
+macro_rules! IS_Z_AT {
+ ($string:expr, $offset:expr) => {
+ CHECK_AT!($string, b'\0', $offset)
+ };
+}
+
+macro_rules! IS_Z {
+ ($string:expr) => {
+ IS_Z_AT!($string, 0)
+ };
+}
+
+macro_rules! IS_BOM {
+ ($string:expr) => {
+ CHECK_AT!($string, b'\xEF', 0)
+ && CHECK_AT!($string, b'\xBB', 1)
+ && CHECK_AT!($string, b'\xBF', 2)
+ };
+}
+
+macro_rules! IS_SPACE_AT {
+ ($string:expr, $offset:expr) => {
+ CHECK_AT!($string, b' ', $offset)
+ };
+}
+
+macro_rules! IS_SPACE {
+ ($string:expr) => {
+ IS_SPACE_AT!($string, 0)
+ };
+}
+
+macro_rules! IS_TAB_AT {
+ ($string:expr, $offset:expr) => {
+ CHECK_AT!($string, b'\t', $offset)
+ };
+}
+
+macro_rules! IS_TAB {
+ ($string:expr) => {
+ IS_TAB_AT!($string, 0)
+ };
+}
+
+macro_rules! IS_BLANK_AT {
+ ($string:expr, $offset:expr) => {
+ IS_SPACE_AT!($string, $offset) || IS_TAB_AT!($string, $offset)
+ };
+}
+
+macro_rules! IS_BLANK {
+ ($string:expr) => {
+ IS_BLANK_AT!($string, 0)
+ };
+}
+
+macro_rules! IS_BREAK_AT {
+ ($string:expr, $offset:expr) => {
+ CHECK_AT!($string, b'\r', $offset)
+ || CHECK_AT!($string, b'\n', $offset)
+ || CHECK_AT!($string, b'\xC2', $offset) && CHECK_AT!($string, b'\x85', $offset + 1)
+ || CHECK_AT!($string, b'\xE2', $offset)
+ && CHECK_AT!($string, b'\x80', $offset + 1)
+ && CHECK_AT!($string, b'\xA8', $offset + 2)
+ || CHECK_AT!($string, b'\xE2', $offset)
+ && CHECK_AT!($string, b'\x80', $offset + 1)
+ && CHECK_AT!($string, b'\xA9', $offset + 2)
+ };
+}
+
+macro_rules! IS_BREAK {
+ ($string:expr) => {
+ IS_BREAK_AT!($string, 0)
+ };
+}
+
+macro_rules! IS_CRLF {
+ ($string:expr) => {
+ CHECK_AT!($string, b'\r', 0) && CHECK_AT!($string, b'\n', 1)
+ };
+}
+
+macro_rules! IS_BREAKZ_AT {
+ ($string:expr, $offset:expr) => {
+ IS_BREAK_AT!($string, $offset) || IS_Z_AT!($string, $offset)
+ };
+}
+
+macro_rules! IS_BREAKZ {
+ ($string:expr) => {
+ IS_BREAKZ_AT!($string, 0)
+ };
+}
+
+macro_rules! IS_BLANKZ_AT {
+ ($string:expr, $offset:expr) => {
+ IS_BLANK_AT!($string, $offset) || IS_BREAKZ_AT!($string, $offset)
+ };
+}
+
+macro_rules! IS_BLANKZ {
+ ($string:expr) => {
+ IS_BLANKZ_AT!($string, 0)
+ };
+}
+
+macro_rules! WIDTH_AT {
+ ($string:expr, $offset:expr) => {
+ if *$string.pointer.wrapping_offset($offset as isize) & 0x80 == 0x00 {
+ 1
+ } else if *$string.pointer.wrapping_offset($offset as isize) & 0xE0 == 0xC0 {
+ 2
+ } else if *$string.pointer.wrapping_offset($offset as isize) & 0xF0 == 0xE0 {
+ 3
+ } else if *$string.pointer.wrapping_offset($offset as isize) & 0xF8 == 0xF0 {
+ 4
+ } else {
+ 0
+ }
+ };
+}
+
+macro_rules! WIDTH {
+ ($string:expr) => {
+ WIDTH_AT!($string, 0)
+ };
+}
+
+macro_rules! MOVE {
+ ($string:expr) => {
+ $string.pointer = $string.pointer.wrapping_offset(WIDTH!($string) as isize)
+ };
+}
+
+macro_rules! COPY {
+ ($string_a:expr, $string_b:expr) => {
+ if *$string_b.pointer & 0x80 == 0x00 {
+ *$string_a.pointer = *$string_b.pointer;
+ $string_a.pointer = $string_a.pointer.wrapping_offset(1);
+ $string_b.pointer = $string_b.pointer.wrapping_offset(1);
+ } else if *$string_b.pointer & 0xE0 == 0xC0 {
+ *$string_a.pointer = *$string_b.pointer;
+ $string_a.pointer = $string_a.pointer.wrapping_offset(1);
+ $string_b.pointer = $string_b.pointer.wrapping_offset(1);
+ *$string_a.pointer = *$string_b.pointer;
+ $string_a.pointer = $string_a.pointer.wrapping_offset(1);
+ $string_b.pointer = $string_b.pointer.wrapping_offset(1);
+ } else if *$string_b.pointer & 0xF0 == 0xE0 {
+ *$string_a.pointer = *$string_b.pointer;
+ $string_a.pointer = $string_a.pointer.wrapping_offset(1);
+ $string_b.pointer = $string_b.pointer.wrapping_offset(1);
+ *$string_a.pointer = *$string_b.pointer;
+ $string_a.pointer = $string_a.pointer.wrapping_offset(1);
+ $string_b.pointer = $string_b.pointer.wrapping_offset(1);
+ *$string_a.pointer = *$string_b.pointer;
+ $string_a.pointer = $string_a.pointer.wrapping_offset(1);
+ $string_b.pointer = $string_b.pointer.wrapping_offset(1);
+ } else if *$string_b.pointer & 0xF8 == 0xF0 {
+ *$string_a.pointer = *$string_b.pointer;
+ $string_a.pointer = $string_a.pointer.wrapping_offset(1);
+ $string_b.pointer = $string_b.pointer.wrapping_offset(1);
+ *$string_a.pointer = *$string_b.pointer;
+ $string_a.pointer = $string_a.pointer.wrapping_offset(1);
+ $string_b.pointer = $string_b.pointer.wrapping_offset(1);
+ *$string_a.pointer = *$string_b.pointer;
+ $string_a.pointer = $string_a.pointer.wrapping_offset(1);
+ $string_b.pointer = $string_b.pointer.wrapping_offset(1);
+ *$string_a.pointer = *$string_b.pointer;
+ $string_a.pointer = $string_a.pointer.wrapping_offset(1);
+ $string_b.pointer = $string_b.pointer.wrapping_offset(1);
+ }
+ };
+}
+
+macro_rules! STACK_INIT {
+ ($stack:expr, $type:ty) => {{
+ $stack.start = yaml_malloc(16 * size_of::<$type>() as libc::c_ulong) as *mut $type;
+ $stack.top = $stack.start;
+ $stack.end = $stack.start.offset(16_isize);
+ }};
+}
+
+macro_rules! STACK_DEL {
+ ($stack:expr) => {
+ yaml_free($stack.start as *mut libc::c_void);
+ $stack.end = ptr::null_mut();
+ $stack.top = ptr::null_mut();
+ $stack.start = ptr::null_mut();
+ };
+}
+
+macro_rules! STACK_EMPTY {
+ ($stack:expr) => {
+ $stack.start == $stack.top
+ };
+}
+
+macro_rules! STACK_LIMIT {
+ ($context:expr, $stack:expr) => {
+ if $stack.top.c_offset_from($stack.start) < libc::c_int::MAX as isize - 1 {
+ OK
+ } else {
+ (*$context).error = YAML_MEMORY_ERROR;
+ FAIL
+ }
+ };
+}
+
+macro_rules! PUSH {
+ (do $stack:expr, $push:expr) => {{
+ if $stack.top == $stack.end {
+ yaml_stack_extend(
+ addr_of_mut!($stack.start) as *mut *mut libc::c_void,
+ addr_of_mut!($stack.top) as *mut *mut libc::c_void,
+ addr_of_mut!($stack.end) as *mut *mut libc::c_void,
+ );
+ }
+ $push;
+ $stack.top = $stack.top.wrapping_offset(1);
+ }};
+ ($stack:expr, *$value:expr) => {
+ PUSH!(do $stack, ptr::copy_nonoverlapping($value, $stack.top, 1))
+ };
+ ($stack:expr, $value:expr) => {
+ PUSH!(do $stack, ptr::write($stack.top, $value))
+ };
+}
+
+macro_rules! POP {
+ ($stack:expr) => {
+ *{
+ $stack.top = $stack.top.offset(-1);
+ $stack.top
+ }
+ };
+}
+
+macro_rules! QUEUE_INIT {
+ ($queue:expr, $type:ty) => {{
+ $queue.start = yaml_malloc(16 * size_of::<$type>() as libc::c_ulong) as *mut $type;
+ $queue.tail = $queue.start;
+ $queue.head = $queue.tail;
+ $queue.end = $queue.start.offset(16_isize);
+ }};
+}
+
+macro_rules! QUEUE_DEL {
+ ($queue:expr) => {
+ yaml_free($queue.start as *mut libc::c_void);
+ $queue.end = ptr::null_mut();
+ $queue.tail = ptr::null_mut();
+ $queue.head = ptr::null_mut();
+ $queue.start = ptr::null_mut();
+ };
+}
+
+macro_rules! QUEUE_EMPTY {
+ ($queue:expr) => {
+ $queue.head == $queue.tail
+ };
+}
+
+macro_rules! ENQUEUE {
+ (do $queue:expr, $enqueue:expr) => {{
+ if $queue.tail == $queue.end {
+ yaml_queue_extend(
+ addr_of_mut!($queue.start) as *mut *mut libc::c_void,
+ addr_of_mut!($queue.head) as *mut *mut libc::c_void,
+ addr_of_mut!($queue.tail) as *mut *mut libc::c_void,
+ addr_of_mut!($queue.end) as *mut *mut libc::c_void,
+ );
+ }
+ $enqueue;
+ $queue.tail = $queue.tail.wrapping_offset(1);
+ }};
+ ($queue:expr, *$value:expr) => {
+ ENQUEUE!(do $queue, ptr::copy_nonoverlapping($value, $queue.tail, 1))
+ };
+ ($queue:expr, $value:expr) => {
+ ENQUEUE!(do $queue, ptr::write($queue.tail, $value))
+ };
+}
+
+macro_rules! DEQUEUE {
+ ($queue:expr) => {
+ *{
+ let head = $queue.head;
+ $queue.head = $queue.head.wrapping_offset(1);
+ head
+ }
+ };
+}
+
+macro_rules! QUEUE_INSERT {
+ ($queue:expr, $index:expr, $value:expr) => {{
+ if $queue.tail == $queue.end {
+ yaml_queue_extend(
+ addr_of_mut!($queue.start) as *mut *mut libc::c_void,
+ addr_of_mut!($queue.head) as *mut *mut libc::c_void,
+ addr_of_mut!($queue.tail) as *mut *mut libc::c_void,
+ addr_of_mut!($queue.end) as *mut *mut libc::c_void,
+ );
+ }
+ memmove(
+ $queue
+ .head
+ .wrapping_offset($index as isize)
+ .wrapping_offset(1_isize) as *mut libc::c_void,
+ $queue.head.wrapping_offset($index as isize) as *const libc::c_void,
+ ($queue.tail.c_offset_from($queue.head) as libc::c_ulong)
+ .wrapping_sub($index)
+ .wrapping_mul(size_of::<yaml_token_t>() as libc::c_ulong),
+ );
+ *$queue.head.wrapping_offset($index as isize) = $value;
+ let fresh14 = addr_of_mut!($queue.tail);
+ *fresh14 = (*fresh14).wrapping_offset(1);
+ }};
+}
diff --git a/src/parser.rs b/src/parser.rs
new file mode 100644
index 0000000..c4f4f35
--- /dev/null
+++ b/src/parser.rs
@@ -0,0 +1,1353 @@
+use crate::api::{yaml_free, yaml_malloc, yaml_stack_extend, yaml_strdup};
+use crate::externs::{memcpy, memset, strcmp, strlen};
+use crate::scanner::yaml_parser_fetch_more_tokens;
+use crate::success::{Success, FAIL, OK};
+use crate::yaml::{size_t, yaml_char_t};
+use crate::{
+ libc, yaml_event_t, yaml_mark_t, yaml_parser_t, yaml_tag_directive_t, yaml_token_t,
+ yaml_version_directive_t, YAML_ALIAS_EVENT, YAML_ALIAS_TOKEN, YAML_ANCHOR_TOKEN,
+ YAML_BLOCK_END_TOKEN, YAML_BLOCK_ENTRY_TOKEN, YAML_BLOCK_MAPPING_START_TOKEN,
+ YAML_BLOCK_MAPPING_STYLE, YAML_BLOCK_SEQUENCE_START_TOKEN, YAML_BLOCK_SEQUENCE_STYLE,
+ YAML_DOCUMENT_END_EVENT, YAML_DOCUMENT_END_TOKEN, YAML_DOCUMENT_START_EVENT,
+ YAML_DOCUMENT_START_TOKEN, YAML_FLOW_ENTRY_TOKEN, YAML_FLOW_MAPPING_END_TOKEN,
+ YAML_FLOW_MAPPING_START_TOKEN, YAML_FLOW_MAPPING_STYLE, YAML_FLOW_SEQUENCE_END_TOKEN,
+ YAML_FLOW_SEQUENCE_START_TOKEN, YAML_FLOW_SEQUENCE_STYLE, YAML_KEY_TOKEN,
+ YAML_MAPPING_END_EVENT, YAML_MAPPING_START_EVENT, YAML_NO_ERROR, YAML_PARSER_ERROR,
+ YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, YAML_PARSE_BLOCK_MAPPING_KEY_STATE,
+ YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE,
+ YAML_PARSE_BLOCK_NODE_STATE, YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE,
+ YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, YAML_PARSE_DOCUMENT_CONTENT_STATE,
+ YAML_PARSE_DOCUMENT_END_STATE, YAML_PARSE_DOCUMENT_START_STATE, YAML_PARSE_END_STATE,
+ YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE,
+ YAML_PARSE_FLOW_MAPPING_KEY_STATE, YAML_PARSE_FLOW_MAPPING_VALUE_STATE,
+ YAML_PARSE_FLOW_NODE_STATE, YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE,
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE,
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE,
+ YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE,
+ YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, YAML_PARSE_STREAM_START_STATE,
+ YAML_PLAIN_SCALAR_STYLE, YAML_SCALAR_EVENT, YAML_SCALAR_TOKEN, YAML_SEQUENCE_END_EVENT,
+ YAML_SEQUENCE_START_EVENT, YAML_STREAM_END_EVENT, YAML_STREAM_END_TOKEN,
+ YAML_STREAM_START_EVENT, YAML_STREAM_START_TOKEN, YAML_TAG_DIRECTIVE_TOKEN, YAML_TAG_TOKEN,
+ YAML_VALUE_TOKEN, YAML_VERSION_DIRECTIVE_TOKEN,
+};
+use core::mem::size_of;
+use core::ptr::{self, addr_of_mut};
+
+unsafe fn PEEK_TOKEN(parser: *mut yaml_parser_t) -> *mut yaml_token_t {
+ if (*parser).token_available || yaml_parser_fetch_more_tokens(parser).ok {
+ (*parser).tokens.head
+ } else {
+ ptr::null_mut::<yaml_token_t>()
+ }
+}
+
+unsafe fn SKIP_TOKEN(parser: *mut yaml_parser_t) {
+ (*parser).token_available = false;
+ let fresh3 = addr_of_mut!((*parser).tokens_parsed);
+ *fresh3 = (*fresh3).wrapping_add(1);
+ (*parser).stream_end_produced = (*(*parser).tokens.head).type_ == YAML_STREAM_END_TOKEN;
+ let fresh4 = addr_of_mut!((*parser).tokens.head);
+ *fresh4 = (*fresh4).wrapping_offset(1);
+}
+
+/// Parse the input stream and produce the next parsing event.
+///
+/// Call the function subsequently to produce a sequence of events corresponding
+/// to the input stream. The initial event has the type YAML_STREAM_START_EVENT
+/// while the ending event has the type YAML_STREAM_END_EVENT.
+///
+/// An application is responsible for freeing any buffers associated with the
+/// produced event object using the yaml_event_delete() function.
+///
+/// An application must not alternate the calls of yaml_parser_parse() with the
+/// calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the
+/// parser.
+pub unsafe fn yaml_parser_parse(parser: *mut yaml_parser_t, event: *mut yaml_event_t) -> Success {
+ __assert!(!parser.is_null());
+ __assert!(!event.is_null());
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ if (*parser).stream_end_produced
+ || (*parser).error != YAML_NO_ERROR
+ || (*parser).state == YAML_PARSE_END_STATE
+ {
+ return OK;
+ }
+ yaml_parser_state_machine(parser, event)
+}
+
+unsafe fn yaml_parser_set_parser_error(
+ parser: *mut yaml_parser_t,
+ problem: *const libc::c_char,
+ problem_mark: yaml_mark_t,
+) {
+ (*parser).error = YAML_PARSER_ERROR;
+ let fresh0 = addr_of_mut!((*parser).problem);
+ *fresh0 = problem;
+ (*parser).problem_mark = problem_mark;
+}
+
+unsafe fn yaml_parser_set_parser_error_context(
+ parser: *mut yaml_parser_t,
+ context: *const libc::c_char,
+ context_mark: yaml_mark_t,
+ problem: *const libc::c_char,
+ problem_mark: yaml_mark_t,
+) {
+ (*parser).error = YAML_PARSER_ERROR;
+ let fresh1 = addr_of_mut!((*parser).context);
+ *fresh1 = context;
+ (*parser).context_mark = context_mark;
+ let fresh2 = addr_of_mut!((*parser).problem);
+ *fresh2 = problem;
+ (*parser).problem_mark = problem_mark;
+}
+
+unsafe fn yaml_parser_state_machine(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ match (*parser).state {
+ YAML_PARSE_STREAM_START_STATE => yaml_parser_parse_stream_start(parser, event),
+ YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE => {
+ yaml_parser_parse_document_start(parser, event, true)
+ }
+ YAML_PARSE_DOCUMENT_START_STATE => yaml_parser_parse_document_start(parser, event, false),
+ YAML_PARSE_DOCUMENT_CONTENT_STATE => yaml_parser_parse_document_content(parser, event),
+ YAML_PARSE_DOCUMENT_END_STATE => yaml_parser_parse_document_end(parser, event),
+ YAML_PARSE_BLOCK_NODE_STATE => yaml_parser_parse_node(parser, event, true, false),
+ YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE => {
+ yaml_parser_parse_node(parser, event, true, true)
+ }
+ YAML_PARSE_FLOW_NODE_STATE => yaml_parser_parse_node(parser, event, false, false),
+ YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE => {
+ yaml_parser_parse_block_sequence_entry(parser, event, true)
+ }
+ YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE => {
+ yaml_parser_parse_block_sequence_entry(parser, event, false)
+ }
+ YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE => {
+ yaml_parser_parse_indentless_sequence_entry(parser, event)
+ }
+ YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE => {
+ yaml_parser_parse_block_mapping_key(parser, event, true)
+ }
+ YAML_PARSE_BLOCK_MAPPING_KEY_STATE => {
+ yaml_parser_parse_block_mapping_key(parser, event, false)
+ }
+ YAML_PARSE_BLOCK_MAPPING_VALUE_STATE => {
+ yaml_parser_parse_block_mapping_value(parser, event)
+ }
+ YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE => {
+ yaml_parser_parse_flow_sequence_entry(parser, event, true)
+ }
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE => {
+ yaml_parser_parse_flow_sequence_entry(parser, event, false)
+ }
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE => {
+ yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)
+ }
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE => {
+ yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)
+ }
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE => {
+ yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)
+ }
+ YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE => {
+ yaml_parser_parse_flow_mapping_key(parser, event, true)
+ }
+ YAML_PARSE_FLOW_MAPPING_KEY_STATE => {
+ yaml_parser_parse_flow_mapping_key(parser, event, false)
+ }
+ YAML_PARSE_FLOW_MAPPING_VALUE_STATE => {
+ yaml_parser_parse_flow_mapping_value(parser, event, false)
+ }
+ YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE => {
+ yaml_parser_parse_flow_mapping_value(parser, event, true)
+ }
+ _ => FAIL,
+ }
+}
+
+unsafe fn yaml_parser_parse_stream_start(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let token: *mut yaml_token_t = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_STREAM_START_TOKEN {
+ yaml_parser_set_parser_error(
+ parser,
+ b"did not find expected <stream-start>\0" as *const u8 as *const libc::c_char,
+ (*token).start_mark,
+ );
+ return FAIL;
+ }
+ (*parser).state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_STREAM_START_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).start_mark;
+ (*event).data.stream_start.encoding = (*token).data.stream_start.encoding;
+ SKIP_TOKEN(parser);
+ OK
+}
+
+unsafe fn yaml_parser_parse_document_start(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ implicit: bool,
+) -> Success {
+ let mut token: *mut yaml_token_t;
+ let mut version_directive: *mut yaml_version_directive_t =
+ ptr::null_mut::<yaml_version_directive_t>();
+ struct TagDirectives {
+ start: *mut yaml_tag_directive_t,
+ end: *mut yaml_tag_directive_t,
+ }
+ let mut tag_directives = TagDirectives {
+ start: ptr::null_mut::<yaml_tag_directive_t>(),
+ end: ptr::null_mut::<yaml_tag_directive_t>(),
+ };
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if !implicit {
+ while (*token).type_ == YAML_DOCUMENT_END_TOKEN {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ }
+ }
+ if implicit
+ && (*token).type_ != YAML_VERSION_DIRECTIVE_TOKEN
+ && (*token).type_ != YAML_TAG_DIRECTIVE_TOKEN
+ && (*token).type_ != YAML_DOCUMENT_START_TOKEN
+ && (*token).type_ != YAML_STREAM_END_TOKEN
+ {
+ if yaml_parser_process_directives(
+ parser,
+ ptr::null_mut::<*mut yaml_version_directive_t>(),
+ ptr::null_mut::<*mut yaml_tag_directive_t>(),
+ ptr::null_mut::<*mut yaml_tag_directive_t>(),
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ PUSH!((*parser).states, YAML_PARSE_DOCUMENT_END_STATE);
+ (*parser).state = YAML_PARSE_BLOCK_NODE_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_DOCUMENT_START_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).start_mark;
+ let fresh9 = addr_of_mut!((*event).data.document_start.version_directive);
+ *fresh9 = ptr::null_mut::<yaml_version_directive_t>();
+ let fresh10 = addr_of_mut!((*event).data.document_start.tag_directives.start);
+ *fresh10 = ptr::null_mut::<yaml_tag_directive_t>();
+ let fresh11 = addr_of_mut!((*event).data.document_start.tag_directives.end);
+ *fresh11 = ptr::null_mut::<yaml_tag_directive_t>();
+ (*event).data.document_start.implicit = true;
+ OK
+ } else if (*token).type_ != YAML_STREAM_END_TOKEN {
+ let end_mark: yaml_mark_t;
+ let start_mark: yaml_mark_t = (*token).start_mark;
+ if yaml_parser_process_directives(
+ parser,
+ addr_of_mut!(version_directive),
+ addr_of_mut!(tag_directives.start),
+ addr_of_mut!(tag_directives.end),
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ token = PEEK_TOKEN(parser);
+ if !token.is_null() {
+ if (*token).type_ != YAML_DOCUMENT_START_TOKEN {
+ yaml_parser_set_parser_error(
+ parser,
+ b"did not find expected <document start>\0" as *const u8 as *const libc::c_char,
+ (*token).start_mark,
+ );
+ } else {
+ PUSH!((*parser).states, YAML_PARSE_DOCUMENT_END_STATE);
+ (*parser).state = YAML_PARSE_DOCUMENT_CONTENT_STATE;
+ end_mark = (*token).end_mark;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_DOCUMENT_START_EVENT;
+ (*event).start_mark = start_mark;
+ (*event).end_mark = end_mark;
+ let fresh14 = addr_of_mut!((*event).data.document_start.version_directive);
+ *fresh14 = version_directive;
+ let fresh15 = addr_of_mut!((*event).data.document_start.tag_directives.start);
+ *fresh15 = tag_directives.start;
+ let fresh16 = addr_of_mut!((*event).data.document_start.tag_directives.end);
+ *fresh16 = tag_directives.end;
+ (*event).data.document_start.implicit = false;
+ SKIP_TOKEN(parser);
+ tag_directives.end = ptr::null_mut::<yaml_tag_directive_t>();
+ tag_directives.start = tag_directives.end;
+ return OK;
+ }
+ }
+ yaml_free(version_directive as *mut libc::c_void);
+ while tag_directives.start != tag_directives.end {
+ yaml_free((*tag_directives.end.wrapping_offset(-1_isize)).handle as *mut libc::c_void);
+ yaml_free((*tag_directives.end.wrapping_offset(-1_isize)).prefix as *mut libc::c_void);
+ tag_directives.end = tag_directives.end.wrapping_offset(-1);
+ }
+ yaml_free(tag_directives.start as *mut libc::c_void);
+ FAIL
+ } else {
+ (*parser).state = YAML_PARSE_END_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_STREAM_END_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ OK
+ }
+}
+
+unsafe fn yaml_parser_parse_document_content(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let token: *mut yaml_token_t = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ == YAML_VERSION_DIRECTIVE_TOKEN
+ || (*token).type_ == YAML_TAG_DIRECTIVE_TOKEN
+ || (*token).type_ == YAML_DOCUMENT_START_TOKEN
+ || (*token).type_ == YAML_DOCUMENT_END_TOKEN
+ || (*token).type_ == YAML_STREAM_END_TOKEN
+ {
+ (*parser).state = POP!((*parser).states);
+ yaml_parser_process_empty_scalar(event, (*token).start_mark)
+ } else {
+ yaml_parser_parse_node(parser, event, true, false)
+ }
+}
+
+unsafe fn yaml_parser_parse_document_end(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let mut end_mark: yaml_mark_t;
+ let mut implicit = true;
+ let token: *mut yaml_token_t = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ end_mark = (*token).start_mark;
+ let start_mark: yaml_mark_t = end_mark;
+ if (*token).type_ == YAML_DOCUMENT_END_TOKEN {
+ end_mark = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ implicit = false;
+ }
+ while !STACK_EMPTY!((*parser).tag_directives) {
+ let tag_directive = POP!((*parser).tag_directives);
+ yaml_free(tag_directive.handle as *mut libc::c_void);
+ yaml_free(tag_directive.prefix as *mut libc::c_void);
+ }
+ (*parser).state = YAML_PARSE_DOCUMENT_START_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_DOCUMENT_END_EVENT;
+ (*event).start_mark = start_mark;
+ (*event).end_mark = end_mark;
+ (*event).data.document_end.implicit = implicit;
+ OK
+}
+
+unsafe fn yaml_parser_parse_node(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ block: bool,
+ indentless_sequence: bool,
+) -> Success {
+ let mut current_block: u64;
+ let mut token: *mut yaml_token_t;
+ let mut anchor: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut tag_handle: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut tag_suffix: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut tag: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut start_mark: yaml_mark_t;
+ let mut end_mark: yaml_mark_t;
+ let mut tag_mark = yaml_mark_t {
+ index: 0,
+ line: 0,
+ column: 0,
+ };
+ let implicit;
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ == YAML_ALIAS_TOKEN {
+ (*parser).state = POP!((*parser).states);
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_ALIAS_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).end_mark;
+ let fresh26 = addr_of_mut!((*event).data.alias.anchor);
+ *fresh26 = (*token).data.alias.value;
+ SKIP_TOKEN(parser);
+ OK
+ } else {
+ end_mark = (*token).start_mark;
+ start_mark = end_mark;
+ if (*token).type_ == YAML_ANCHOR_TOKEN {
+ anchor = (*token).data.anchor.value;
+ start_mark = (*token).start_mark;
+ end_mark = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ current_block = 17786380918591080555;
+ } else if (*token).type_ == YAML_TAG_TOKEN {
+ tag_handle = (*token).data.tag.handle;
+ tag_suffix = (*token).data.tag.suffix;
+ tag_mark = (*token).start_mark;
+ end_mark = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ current_block = 17786380918591080555;
+ } else {
+ current_block = 11743904203796629665;
+ }
+ } else {
+ current_block = 11743904203796629665;
+ }
+ } else if (*token).type_ == YAML_TAG_TOKEN {
+ tag_handle = (*token).data.tag.handle;
+ tag_suffix = (*token).data.tag.suffix;
+ tag_mark = (*token).start_mark;
+ start_mark = tag_mark;
+ end_mark = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ current_block = 17786380918591080555;
+ } else if (*token).type_ == YAML_ANCHOR_TOKEN {
+ anchor = (*token).data.anchor.value;
+ end_mark = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ current_block = 17786380918591080555;
+ } else {
+ current_block = 11743904203796629665;
+ }
+ } else {
+ current_block = 11743904203796629665;
+ }
+ } else {
+ current_block = 11743904203796629665;
+ }
+ if current_block == 11743904203796629665 {
+ if !tag_handle.is_null() {
+ if *tag_handle == 0 {
+ tag = tag_suffix;
+ yaml_free(tag_handle as *mut libc::c_void);
+ tag_suffix = ptr::null_mut::<yaml_char_t>();
+ tag_handle = tag_suffix;
+ current_block = 9437013279121998969;
+ } else {
+ let mut tag_directive: *mut yaml_tag_directive_t;
+ tag_directive = (*parser).tag_directives.start;
+ loop {
+ if !(tag_directive != (*parser).tag_directives.top) {
+ current_block = 17728966195399430138;
+ break;
+ }
+ if strcmp(
+ (*tag_directive).handle as *mut libc::c_char,
+ tag_handle as *mut libc::c_char,
+ ) == 0
+ {
+ let prefix_len: size_t =
+ strlen((*tag_directive).prefix as *mut libc::c_char);
+ let suffix_len: size_t = strlen(tag_suffix as *mut libc::c_char);
+ tag = yaml_malloc(
+ prefix_len.wrapping_add(suffix_len).wrapping_add(1_u64),
+ ) as *mut yaml_char_t;
+ memcpy(
+ tag as *mut libc::c_void,
+ (*tag_directive).prefix as *const libc::c_void,
+ prefix_len,
+ );
+ memcpy(
+ tag.wrapping_offset(prefix_len as isize) as *mut libc::c_void,
+ tag_suffix as *const libc::c_void,
+ suffix_len,
+ );
+ *tag.wrapping_offset(prefix_len.wrapping_add(suffix_len) as isize) =
+ b'\0';
+ yaml_free(tag_handle as *mut libc::c_void);
+ yaml_free(tag_suffix as *mut libc::c_void);
+ tag_suffix = ptr::null_mut::<yaml_char_t>();
+ tag_handle = tag_suffix;
+ current_block = 17728966195399430138;
+ break;
+ } else {
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ }
+ if current_block != 17786380918591080555 {
+ if tag.is_null() {
+ yaml_parser_set_parser_error_context(
+ parser,
+ b"while parsing a node\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found undefined tag handle\0" as *const u8 as *const libc::c_char,
+ tag_mark,
+ );
+ current_block = 17786380918591080555;
+ } else {
+ current_block = 9437013279121998969;
+ }
+ }
+ }
+ } else {
+ current_block = 9437013279121998969;
+ }
+ if current_block != 17786380918591080555 {
+ implicit = tag.is_null() || *tag == 0;
+ if indentless_sequence && (*token).type_ == YAML_BLOCK_ENTRY_TOKEN {
+ end_mark = (*token).end_mark;
+ (*parser).state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SEQUENCE_START_EVENT;
+ (*event).start_mark = start_mark;
+ (*event).end_mark = end_mark;
+ let fresh37 = addr_of_mut!((*event).data.sequence_start.anchor);
+ *fresh37 = anchor;
+ let fresh38 = addr_of_mut!((*event).data.sequence_start.tag);
+ *fresh38 = tag;
+ (*event).data.sequence_start.implicit = implicit;
+ (*event).data.sequence_start.style = YAML_BLOCK_SEQUENCE_STYLE;
+ return OK;
+ } else if (*token).type_ == YAML_SCALAR_TOKEN {
+ let mut plain_implicit = false;
+ let mut quoted_implicit = false;
+ end_mark = (*token).end_mark;
+ if (*token).data.scalar.style == YAML_PLAIN_SCALAR_STYLE && tag.is_null()
+ || !tag.is_null()
+ && strcmp(
+ tag as *mut libc::c_char,
+ b"!\0" as *const u8 as *const libc::c_char,
+ ) == 0
+ {
+ plain_implicit = true;
+ } else if tag.is_null() {
+ quoted_implicit = true;
+ }
+ (*parser).state = POP!((*parser).states);
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SCALAR_EVENT;
+ (*event).start_mark = start_mark;
+ (*event).end_mark = end_mark;
+ let fresh40 = addr_of_mut!((*event).data.scalar.anchor);
+ *fresh40 = anchor;
+ let fresh41 = addr_of_mut!((*event).data.scalar.tag);
+ *fresh41 = tag;
+ let fresh42 = addr_of_mut!((*event).data.scalar.value);
+ *fresh42 = (*token).data.scalar.value;
+ (*event).data.scalar.length = (*token).data.scalar.length;
+ (*event).data.scalar.plain_implicit = plain_implicit;
+ (*event).data.scalar.quoted_implicit = quoted_implicit;
+ (*event).data.scalar.style = (*token).data.scalar.style;
+ SKIP_TOKEN(parser);
+ return OK;
+ } else if (*token).type_ == YAML_FLOW_SEQUENCE_START_TOKEN {
+ end_mark = (*token).end_mark;
+ (*parser).state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SEQUENCE_START_EVENT;
+ (*event).start_mark = start_mark;
+ (*event).end_mark = end_mark;
+ let fresh45 = addr_of_mut!((*event).data.sequence_start.anchor);
+ *fresh45 = anchor;
+ let fresh46 = addr_of_mut!((*event).data.sequence_start.tag);
+ *fresh46 = tag;
+ (*event).data.sequence_start.implicit = implicit;
+ (*event).data.sequence_start.style = YAML_FLOW_SEQUENCE_STYLE;
+ return OK;
+ } else if (*token).type_ == YAML_FLOW_MAPPING_START_TOKEN {
+ end_mark = (*token).end_mark;
+ (*parser).state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_MAPPING_START_EVENT;
+ (*event).start_mark = start_mark;
+ (*event).end_mark = end_mark;
+ let fresh47 = addr_of_mut!((*event).data.mapping_start.anchor);
+ *fresh47 = anchor;
+ let fresh48 = addr_of_mut!((*event).data.mapping_start.tag);
+ *fresh48 = tag;
+ (*event).data.mapping_start.implicit = implicit;
+ (*event).data.mapping_start.style = YAML_FLOW_MAPPING_STYLE;
+ return OK;
+ } else if block && (*token).type_ == YAML_BLOCK_SEQUENCE_START_TOKEN {
+ end_mark = (*token).end_mark;
+ (*parser).state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SEQUENCE_START_EVENT;
+ (*event).start_mark = start_mark;
+ (*event).end_mark = end_mark;
+ let fresh49 = addr_of_mut!((*event).data.sequence_start.anchor);
+ *fresh49 = anchor;
+ let fresh50 = addr_of_mut!((*event).data.sequence_start.tag);
+ *fresh50 = tag;
+ (*event).data.sequence_start.implicit = implicit;
+ (*event).data.sequence_start.style = YAML_BLOCK_SEQUENCE_STYLE;
+ return OK;
+ } else if block && (*token).type_ == YAML_BLOCK_MAPPING_START_TOKEN {
+ end_mark = (*token).end_mark;
+ (*parser).state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_MAPPING_START_EVENT;
+ (*event).start_mark = start_mark;
+ (*event).end_mark = end_mark;
+ let fresh51 = addr_of_mut!((*event).data.mapping_start.anchor);
+ *fresh51 = anchor;
+ let fresh52 = addr_of_mut!((*event).data.mapping_start.tag);
+ *fresh52 = tag;
+ (*event).data.mapping_start.implicit = implicit;
+ (*event).data.mapping_start.style = YAML_BLOCK_MAPPING_STYLE;
+ return OK;
+ } else if !anchor.is_null() || !tag.is_null() {
+ let value: *mut yaml_char_t = yaml_malloc(1_u64) as *mut yaml_char_t;
+ *value = b'\0';
+ (*parser).state = POP!((*parser).states);
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SCALAR_EVENT;
+ (*event).start_mark = start_mark;
+ (*event).end_mark = end_mark;
+ let fresh54 = addr_of_mut!((*event).data.scalar.anchor);
+ *fresh54 = anchor;
+ let fresh55 = addr_of_mut!((*event).data.scalar.tag);
+ *fresh55 = tag;
+ let fresh56 = addr_of_mut!((*event).data.scalar.value);
+ *fresh56 = value;
+ (*event).data.scalar.length = 0_u64;
+ (*event).data.scalar.plain_implicit = implicit;
+ (*event).data.scalar.quoted_implicit = false;
+ (*event).data.scalar.style = YAML_PLAIN_SCALAR_STYLE;
+ return OK;
+ } else {
+ yaml_parser_set_parser_error_context(
+ parser,
+ if block {
+ b"while parsing a block node\0" as *const u8 as *const libc::c_char
+ } else {
+ b"while parsing a flow node\0" as *const u8 as *const libc::c_char
+ },
+ start_mark,
+ b"did not find expected node content\0" as *const u8 as *const libc::c_char,
+ (*token).start_mark,
+ );
+ }
+ }
+ }
+ yaml_free(anchor as *mut libc::c_void);
+ yaml_free(tag_handle as *mut libc::c_void);
+ yaml_free(tag_suffix as *mut libc::c_void);
+ yaml_free(tag as *mut libc::c_void);
+ FAIL
+ }
+}
+
+unsafe fn yaml_parser_parse_block_sequence_entry(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ first: bool,
+) -> Success {
+ let mut token: *mut yaml_token_t;
+ if first {
+ token = PEEK_TOKEN(parser);
+ PUSH!((*parser).marks, (*token).start_mark);
+ SKIP_TOKEN(parser);
+ }
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ == YAML_BLOCK_ENTRY_TOKEN {
+ let mark: yaml_mark_t = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_BLOCK_ENTRY_TOKEN && (*token).type_ != YAML_BLOCK_END_TOKEN {
+ PUSH!((*parser).states, YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE);
+ yaml_parser_parse_node(parser, event, true, false)
+ } else {
+ (*parser).state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE;
+ yaml_parser_process_empty_scalar(event, mark)
+ }
+ } else if (*token).type_ == YAML_BLOCK_END_TOKEN {
+ (*parser).state = POP!((*parser).states);
+ let _ = POP!((*parser).marks);
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SEQUENCE_END_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ OK
+ } else {
+ yaml_parser_set_parser_error_context(
+ parser,
+ b"while parsing a block collection\0" as *const u8 as *const libc::c_char,
+ POP!((*parser).marks),
+ b"did not find expected '-' indicator\0" as *const u8 as *const libc::c_char,
+ (*token).start_mark,
+ );
+ FAIL
+ }
+}
+
+unsafe fn yaml_parser_parse_indentless_sequence_entry(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let mut token: *mut yaml_token_t;
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ == YAML_BLOCK_ENTRY_TOKEN {
+ let mark: yaml_mark_t = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_BLOCK_ENTRY_TOKEN
+ && (*token).type_ != YAML_KEY_TOKEN
+ && (*token).type_ != YAML_VALUE_TOKEN
+ && (*token).type_ != YAML_BLOCK_END_TOKEN
+ {
+ PUSH!((*parser).states, YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE);
+ yaml_parser_parse_node(parser, event, true, false)
+ } else {
+ (*parser).state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE;
+ yaml_parser_process_empty_scalar(event, mark)
+ }
+ } else {
+ (*parser).state = POP!((*parser).states);
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SEQUENCE_END_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).start_mark;
+ OK
+ }
+}
+
+unsafe fn yaml_parser_parse_block_mapping_key(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ first: bool,
+) -> Success {
+ let mut token: *mut yaml_token_t;
+ if first {
+ token = PEEK_TOKEN(parser);
+ PUSH!((*parser).marks, (*token).start_mark);
+ SKIP_TOKEN(parser);
+ }
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ == YAML_KEY_TOKEN {
+ let mark: yaml_mark_t = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_KEY_TOKEN
+ && (*token).type_ != YAML_VALUE_TOKEN
+ && (*token).type_ != YAML_BLOCK_END_TOKEN
+ {
+ PUSH!((*parser).states, YAML_PARSE_BLOCK_MAPPING_VALUE_STATE);
+ yaml_parser_parse_node(parser, event, true, true)
+ } else {
+ (*parser).state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE;
+ yaml_parser_process_empty_scalar(event, mark)
+ }
+ } else if (*token).type_ == YAML_BLOCK_END_TOKEN {
+ (*parser).state = POP!((*parser).states);
+ let _ = POP!((*parser).marks);
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_MAPPING_END_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ OK
+ } else {
+ yaml_parser_set_parser_error_context(
+ parser,
+ b"while parsing a block mapping\0" as *const u8 as *const libc::c_char,
+ POP!((*parser).marks),
+ b"did not find expected key\0" as *const u8 as *const libc::c_char,
+ (*token).start_mark,
+ );
+ FAIL
+ }
+}
+
+unsafe fn yaml_parser_parse_block_mapping_value(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let mut token: *mut yaml_token_t;
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ == YAML_VALUE_TOKEN {
+ let mark: yaml_mark_t = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_KEY_TOKEN
+ && (*token).type_ != YAML_VALUE_TOKEN
+ && (*token).type_ != YAML_BLOCK_END_TOKEN
+ {
+ PUSH!((*parser).states, YAML_PARSE_BLOCK_MAPPING_KEY_STATE);
+ yaml_parser_parse_node(parser, event, true, true)
+ } else {
+ (*parser).state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
+ yaml_parser_process_empty_scalar(event, mark)
+ }
+ } else {
+ (*parser).state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE;
+ yaml_parser_process_empty_scalar(event, (*token).start_mark)
+ }
+}
+
+unsafe fn yaml_parser_parse_flow_sequence_entry(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ first: bool,
+) -> Success {
+ let mut token: *mut yaml_token_t;
+ if first {
+ token = PEEK_TOKEN(parser);
+ PUSH!((*parser).marks, (*token).start_mark);
+ SKIP_TOKEN(parser);
+ }
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_FLOW_SEQUENCE_END_TOKEN {
+ if !first {
+ if (*token).type_ == YAML_FLOW_ENTRY_TOKEN {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ } else {
+ yaml_parser_set_parser_error_context(
+ parser,
+ b"while parsing a flow sequence\0" as *const u8 as *const libc::c_char,
+ POP!((*parser).marks),
+ b"did not find expected ',' or ']'\0" as *const u8 as *const libc::c_char,
+ (*token).start_mark,
+ );
+ return FAIL;
+ }
+ }
+ if (*token).type_ == YAML_KEY_TOKEN {
+ (*parser).state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_MAPPING_START_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).end_mark;
+ let fresh99 = addr_of_mut!((*event).data.mapping_start.anchor);
+ *fresh99 = ptr::null_mut::<yaml_char_t>();
+ let fresh100 = addr_of_mut!((*event).data.mapping_start.tag);
+ *fresh100 = ptr::null_mut::<yaml_char_t>();
+ (*event).data.mapping_start.implicit = true;
+ (*event).data.mapping_start.style = YAML_FLOW_MAPPING_STYLE;
+ SKIP_TOKEN(parser);
+ return OK;
+ } else if (*token).type_ != YAML_FLOW_SEQUENCE_END_TOKEN {
+ PUSH!((*parser).states, YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE);
+ return yaml_parser_parse_node(parser, event, false, false);
+ }
+ }
+ (*parser).state = POP!((*parser).states);
+ let _ = POP!((*parser).marks);
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SEQUENCE_END_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ OK
+}
+
+unsafe fn yaml_parser_parse_flow_sequence_entry_mapping_key(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let token: *mut yaml_token_t = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_VALUE_TOKEN
+ && (*token).type_ != YAML_FLOW_ENTRY_TOKEN
+ && (*token).type_ != YAML_FLOW_SEQUENCE_END_TOKEN
+ {
+ PUSH!(
+ (*parser).states,
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE
+ );
+ yaml_parser_parse_node(parser, event, false, false)
+ } else {
+ let mark: yaml_mark_t = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ (*parser).state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE;
+ yaml_parser_process_empty_scalar(event, mark)
+ }
+}
+
+unsafe fn yaml_parser_parse_flow_sequence_entry_mapping_value(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let mut token: *mut yaml_token_t;
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ == YAML_VALUE_TOKEN {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_FLOW_ENTRY_TOKEN && (*token).type_ != YAML_FLOW_SEQUENCE_END_TOKEN
+ {
+ PUSH!(
+ (*parser).states,
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE
+ );
+ return yaml_parser_parse_node(parser, event, false, false);
+ }
+ }
+ (*parser).state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE;
+ yaml_parser_process_empty_scalar(event, (*token).start_mark)
+}
+
+unsafe fn yaml_parser_parse_flow_sequence_entry_mapping_end(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+) -> Success {
+ let token: *mut yaml_token_t = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ (*parser).state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE;
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_MAPPING_END_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).start_mark;
+ OK
+}
+
+unsafe fn yaml_parser_parse_flow_mapping_key(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ first: bool,
+) -> Success {
+ let mut token: *mut yaml_token_t;
+ if first {
+ token = PEEK_TOKEN(parser);
+ PUSH!((*parser).marks, (*token).start_mark);
+ SKIP_TOKEN(parser);
+ }
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_FLOW_MAPPING_END_TOKEN {
+ if !first {
+ if (*token).type_ == YAML_FLOW_ENTRY_TOKEN {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ } else {
+ yaml_parser_set_parser_error_context(
+ parser,
+ b"while parsing a flow mapping\0" as *const u8 as *const libc::c_char,
+ POP!((*parser).marks),
+ b"did not find expected ',' or '}'\0" as *const u8 as *const libc::c_char,
+ (*token).start_mark,
+ );
+ return FAIL;
+ }
+ }
+ if (*token).type_ == YAML_KEY_TOKEN {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_VALUE_TOKEN
+ && (*token).type_ != YAML_FLOW_ENTRY_TOKEN
+ && (*token).type_ != YAML_FLOW_MAPPING_END_TOKEN
+ {
+ PUSH!((*parser).states, YAML_PARSE_FLOW_MAPPING_VALUE_STATE);
+ return yaml_parser_parse_node(parser, event, false, false);
+ } else {
+ (*parser).state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE;
+ return yaml_parser_process_empty_scalar(event, (*token).start_mark);
+ }
+ } else if (*token).type_ != YAML_FLOW_MAPPING_END_TOKEN {
+ PUSH!((*parser).states, YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE);
+ return yaml_parser_parse_node(parser, event, false, false);
+ }
+ }
+ (*parser).state = POP!((*parser).states);
+ let _ = POP!((*parser).marks);
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_MAPPING_END_EVENT;
+ (*event).start_mark = (*token).start_mark;
+ (*event).end_mark = (*token).end_mark;
+ SKIP_TOKEN(parser);
+ OK
+}
+
+unsafe fn yaml_parser_parse_flow_mapping_value(
+ parser: *mut yaml_parser_t,
+ event: *mut yaml_event_t,
+ empty: bool,
+) -> Success {
+ let mut token: *mut yaml_token_t;
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if empty {
+ (*parser).state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
+ return yaml_parser_process_empty_scalar(event, (*token).start_mark);
+ }
+ if (*token).type_ == YAML_VALUE_TOKEN {
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ return FAIL;
+ }
+ if (*token).type_ != YAML_FLOW_ENTRY_TOKEN && (*token).type_ != YAML_FLOW_MAPPING_END_TOKEN
+ {
+ PUSH!((*parser).states, YAML_PARSE_FLOW_MAPPING_KEY_STATE);
+ return yaml_parser_parse_node(parser, event, false, false);
+ }
+ }
+ (*parser).state = YAML_PARSE_FLOW_MAPPING_KEY_STATE;
+ yaml_parser_process_empty_scalar(event, (*token).start_mark)
+}
+
+unsafe fn yaml_parser_process_empty_scalar(event: *mut yaml_event_t, mark: yaml_mark_t) -> Success {
+ let value: *mut yaml_char_t = yaml_malloc(1_u64) as *mut yaml_char_t;
+ *value = b'\0';
+ memset(
+ event as *mut libc::c_void,
+ 0,
+ size_of::<yaml_event_t>() as libc::c_ulong,
+ );
+ (*event).type_ = YAML_SCALAR_EVENT;
+ (*event).start_mark = mark;
+ (*event).end_mark = mark;
+ let fresh138 = addr_of_mut!((*event).data.scalar.anchor);
+ *fresh138 = ptr::null_mut::<yaml_char_t>();
+ let fresh139 = addr_of_mut!((*event).data.scalar.tag);
+ *fresh139 = ptr::null_mut::<yaml_char_t>();
+ let fresh140 = addr_of_mut!((*event).data.scalar.value);
+ *fresh140 = value;
+ (*event).data.scalar.length = 0_u64;
+ (*event).data.scalar.plain_implicit = true;
+ (*event).data.scalar.quoted_implicit = false;
+ (*event).data.scalar.style = YAML_PLAIN_SCALAR_STYLE;
+ OK
+}
+
+unsafe fn yaml_parser_process_directives(
+ parser: *mut yaml_parser_t,
+ version_directive_ref: *mut *mut yaml_version_directive_t,
+ tag_directives_start_ref: *mut *mut yaml_tag_directive_t,
+ tag_directives_end_ref: *mut *mut yaml_tag_directive_t,
+) -> Success {
+ let mut current_block: u64;
+ let mut default_tag_directives: [yaml_tag_directive_t; 3] = [
+ yaml_tag_directive_t {
+ handle: b"!\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
+ prefix: b"!\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
+ },
+ yaml_tag_directive_t {
+ handle: b"!!\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
+ prefix: b"tag:yaml.org,2002:\0" as *const u8 as *const libc::c_char as *mut yaml_char_t,
+ },
+ yaml_tag_directive_t {
+ handle: ptr::null_mut::<yaml_char_t>(),
+ prefix: ptr::null_mut::<yaml_char_t>(),
+ },
+ ];
+ let mut default_tag_directive: *mut yaml_tag_directive_t;
+ let mut version_directive: *mut yaml_version_directive_t =
+ ptr::null_mut::<yaml_version_directive_t>();
+ struct TagDirectives {
+ start: *mut yaml_tag_directive_t,
+ end: *mut yaml_tag_directive_t,
+ top: *mut yaml_tag_directive_t,
+ }
+ let mut tag_directives = TagDirectives {
+ start: ptr::null_mut::<yaml_tag_directive_t>(),
+ end: ptr::null_mut::<yaml_tag_directive_t>(),
+ top: ptr::null_mut::<yaml_tag_directive_t>(),
+ };
+ let mut token: *mut yaml_token_t;
+ STACK_INIT!(tag_directives, yaml_tag_directive_t);
+ token = PEEK_TOKEN(parser);
+ if !token.is_null() {
+ loop {
+ if !((*token).type_ == YAML_VERSION_DIRECTIVE_TOKEN
+ || (*token).type_ == YAML_TAG_DIRECTIVE_TOKEN)
+ {
+ current_block = 16924917904204750491;
+ break;
+ }
+ if (*token).type_ == YAML_VERSION_DIRECTIVE_TOKEN {
+ if !version_directive.is_null() {
+ yaml_parser_set_parser_error(
+ parser,
+ b"found duplicate %YAML directive\0" as *const u8 as *const libc::c_char,
+ (*token).start_mark,
+ );
+ current_block = 17143798186130252483;
+ break;
+ } else if (*token).data.version_directive.major != 1
+ || (*token).data.version_directive.minor != 1
+ && (*token).data.version_directive.minor != 2
+ {
+ yaml_parser_set_parser_error(
+ parser,
+ b"found incompatible YAML document\0" as *const u8 as *const libc::c_char,
+ (*token).start_mark,
+ );
+ current_block = 17143798186130252483;
+ break;
+ } else {
+ version_directive =
+ yaml_malloc(size_of::<yaml_version_directive_t>() as libc::c_ulong)
+ as *mut yaml_version_directive_t;
+ (*version_directive).major = (*token).data.version_directive.major;
+ (*version_directive).minor = (*token).data.version_directive.minor;
+ }
+ } else if (*token).type_ == YAML_TAG_DIRECTIVE_TOKEN {
+ let value = yaml_tag_directive_t {
+ handle: (*token).data.tag_directive.handle,
+ prefix: (*token).data.tag_directive.prefix,
+ };
+ if yaml_parser_append_tag_directive(parser, value, false, (*token).start_mark).fail
+ {
+ current_block = 17143798186130252483;
+ break;
+ }
+ PUSH!(tag_directives, value);
+ }
+ SKIP_TOKEN(parser);
+ token = PEEK_TOKEN(parser);
+ if token.is_null() {
+ current_block = 17143798186130252483;
+ break;
+ }
+ }
+ if current_block != 17143798186130252483 {
+ default_tag_directive = default_tag_directives.as_mut_ptr();
+ loop {
+ if (*default_tag_directive).handle.is_null() {
+ current_block = 18377268871191777778;
+ break;
+ }
+ if yaml_parser_append_tag_directive(
+ parser,
+ *default_tag_directive,
+ true,
+ (*token).start_mark,
+ )
+ .fail
+ {
+ current_block = 17143798186130252483;
+ break;
+ }
+ default_tag_directive = default_tag_directive.wrapping_offset(1);
+ }
+ if current_block != 17143798186130252483 {
+ if !version_directive_ref.is_null() {
+ *version_directive_ref = version_directive;
+ }
+ if !tag_directives_start_ref.is_null() {
+ if STACK_EMPTY!(tag_directives) {
+ *tag_directives_end_ref = ptr::null_mut::<yaml_tag_directive_t>();
+ *tag_directives_start_ref = *tag_directives_end_ref;
+ STACK_DEL!(tag_directives);
+ } else {
+ *tag_directives_start_ref = tag_directives.start;
+ *tag_directives_end_ref = tag_directives.top;
+ }
+ } else {
+ STACK_DEL!(tag_directives);
+ }
+ if version_directive_ref.is_null() {
+ yaml_free(version_directive as *mut libc::c_void);
+ }
+ return OK;
+ }
+ }
+ }
+ yaml_free(version_directive as *mut libc::c_void);
+ while !STACK_EMPTY!(tag_directives) {
+ let tag_directive = POP!(tag_directives);
+ yaml_free(tag_directive.handle as *mut libc::c_void);
+ yaml_free(tag_directive.prefix as *mut libc::c_void);
+ }
+ STACK_DEL!(tag_directives);
+ FAIL
+}
+
+unsafe fn yaml_parser_append_tag_directive(
+ parser: *mut yaml_parser_t,
+ value: yaml_tag_directive_t,
+ allow_duplicates: bool,
+ mark: yaml_mark_t,
+) -> Success {
+ let mut tag_directive: *mut yaml_tag_directive_t;
+ let mut copy = yaml_tag_directive_t {
+ handle: ptr::null_mut::<yaml_char_t>(),
+ prefix: ptr::null_mut::<yaml_char_t>(),
+ };
+ tag_directive = (*parser).tag_directives.start;
+ while tag_directive != (*parser).tag_directives.top {
+ if strcmp(
+ value.handle as *mut libc::c_char,
+ (*tag_directive).handle as *mut libc::c_char,
+ ) == 0
+ {
+ if allow_duplicates {
+ return OK;
+ }
+ yaml_parser_set_parser_error(
+ parser,
+ b"found duplicate %TAG directive\0" as *const u8 as *const libc::c_char,
+ mark,
+ );
+ return FAIL;
+ }
+ tag_directive = tag_directive.wrapping_offset(1);
+ }
+ copy.handle = yaml_strdup(value.handle);
+ copy.prefix = yaml_strdup(value.prefix);
+ PUSH!((*parser).tag_directives, copy);
+ OK
+}
diff --git a/src/reader.rs b/src/reader.rs
new file mode 100644
index 0000000..264ad92
--- /dev/null
+++ b/src/reader.rs
@@ -0,0 +1,469 @@
+use crate::externs::{memcmp, memmove};
+use crate::success::{Success, FAIL, OK};
+use crate::yaml::{size_t, yaml_char_t};
+use crate::{
+ libc, yaml_parser_t, PointerExt, YAML_ANY_ENCODING, YAML_READER_ERROR, YAML_UTF16BE_ENCODING,
+ YAML_UTF16LE_ENCODING, YAML_UTF8_ENCODING,
+};
+use core::ptr::addr_of_mut;
+
+unsafe fn yaml_parser_set_reader_error(
+ parser: *mut yaml_parser_t,
+ problem: *const libc::c_char,
+ offset: size_t,
+ value: libc::c_int,
+) -> Success {
+ (*parser).error = YAML_READER_ERROR;
+ let fresh0 = addr_of_mut!((*parser).problem);
+ *fresh0 = problem;
+ (*parser).problem_offset = offset;
+ (*parser).problem_value = value;
+ FAIL
+}
+
+const BOM_UTF8: *const libc::c_char = b"\xEF\xBB\xBF\0" as *const u8 as *const libc::c_char;
+const BOM_UTF16LE: *const libc::c_char = b"\xFF\xFE\0" as *const u8 as *const libc::c_char;
+const BOM_UTF16BE: *const libc::c_char = b"\xFE\xFF\0" as *const u8 as *const libc::c_char;
+
+unsafe fn yaml_parser_determine_encoding(parser: *mut yaml_parser_t) -> Success {
+ while !(*parser).eof
+ && ((*parser)
+ .raw_buffer
+ .last
+ .c_offset_from((*parser).raw_buffer.pointer) as libc::c_long)
+ < 3_i64
+ {
+ if yaml_parser_update_raw_buffer(parser).fail {
+ return FAIL;
+ }
+ }
+ if (*parser)
+ .raw_buffer
+ .last
+ .c_offset_from((*parser).raw_buffer.pointer) as libc::c_long
+ >= 2_i64
+ && memcmp(
+ (*parser).raw_buffer.pointer as *const libc::c_void,
+ BOM_UTF16LE as *const libc::c_void,
+ 2_u64,
+ ) == 0
+ {
+ (*parser).encoding = YAML_UTF16LE_ENCODING;
+ let fresh1 = addr_of_mut!((*parser).raw_buffer.pointer);
+ *fresh1 = (*fresh1).wrapping_offset(2_isize);
+ let fresh2 = addr_of_mut!((*parser).offset);
+ *fresh2 = (*fresh2 as libc::c_ulong).wrapping_add(2_u64) as size_t as size_t;
+ } else if (*parser)
+ .raw_buffer
+ .last
+ .c_offset_from((*parser).raw_buffer.pointer) as libc::c_long
+ >= 2_i64
+ && memcmp(
+ (*parser).raw_buffer.pointer as *const libc::c_void,
+ BOM_UTF16BE as *const libc::c_void,
+ 2_u64,
+ ) == 0
+ {
+ (*parser).encoding = YAML_UTF16BE_ENCODING;
+ let fresh3 = addr_of_mut!((*parser).raw_buffer.pointer);
+ *fresh3 = (*fresh3).wrapping_offset(2_isize);
+ let fresh4 = addr_of_mut!((*parser).offset);
+ *fresh4 = (*fresh4 as libc::c_ulong).wrapping_add(2_u64) as size_t as size_t;
+ } else if (*parser)
+ .raw_buffer
+ .last
+ .c_offset_from((*parser).raw_buffer.pointer) as libc::c_long
+ >= 3_i64
+ && memcmp(
+ (*parser).raw_buffer.pointer as *const libc::c_void,
+ BOM_UTF8 as *const libc::c_void,
+ 3_u64,
+ ) == 0
+ {
+ (*parser).encoding = YAML_UTF8_ENCODING;
+ let fresh5 = addr_of_mut!((*parser).raw_buffer.pointer);
+ *fresh5 = (*fresh5).wrapping_offset(3_isize);
+ let fresh6 = addr_of_mut!((*parser).offset);
+ *fresh6 = (*fresh6 as libc::c_ulong).wrapping_add(3_u64) as size_t as size_t;
+ } else {
+ (*parser).encoding = YAML_UTF8_ENCODING;
+ }
+ OK
+}
+
+unsafe fn yaml_parser_update_raw_buffer(parser: *mut yaml_parser_t) -> Success {
+ let mut size_read: size_t = 0_u64;
+ if (*parser).raw_buffer.start == (*parser).raw_buffer.pointer
+ && (*parser).raw_buffer.last == (*parser).raw_buffer.end
+ {
+ return OK;
+ }
+ if (*parser).eof {
+ return OK;
+ }
+ if (*parser).raw_buffer.start < (*parser).raw_buffer.pointer
+ && (*parser).raw_buffer.pointer < (*parser).raw_buffer.last
+ {
+ memmove(
+ (*parser).raw_buffer.start as *mut libc::c_void,
+ (*parser).raw_buffer.pointer as *const libc::c_void,
+ (*parser)
+ .raw_buffer
+ .last
+ .c_offset_from((*parser).raw_buffer.pointer) as libc::c_long
+ as libc::c_ulong,
+ );
+ }
+ let fresh7 = addr_of_mut!((*parser).raw_buffer.last);
+ *fresh7 = (*fresh7).wrapping_offset(
+ -((*parser)
+ .raw_buffer
+ .pointer
+ .c_offset_from((*parser).raw_buffer.start) as libc::c_long as isize),
+ );
+ let fresh8 = addr_of_mut!((*parser).raw_buffer.pointer);
+ *fresh8 = (*parser).raw_buffer.start;
+ if (*parser).read_handler.expect("non-null function pointer")(
+ (*parser).read_handler_data,
+ (*parser).raw_buffer.last,
+ (*parser)
+ .raw_buffer
+ .end
+ .c_offset_from((*parser).raw_buffer.last) as libc::c_long as size_t,
+ addr_of_mut!(size_read),
+ ) == 0
+ {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"input error\0" as *const u8 as *const libc::c_char,
+ (*parser).offset,
+ -1,
+ );
+ }
+ let fresh9 = addr_of_mut!((*parser).raw_buffer.last);
+ *fresh9 = (*fresh9).wrapping_offset(size_read as isize);
+ if size_read == 0 {
+ (*parser).eof = true;
+ }
+ OK
+}
+
+pub(crate) unsafe fn yaml_parser_update_buffer(
+ parser: *mut yaml_parser_t,
+ length: size_t,
+) -> Success {
+ let mut first = true;
+ __assert!(((*parser).read_handler).is_some());
+ if (*parser).eof && (*parser).raw_buffer.pointer == (*parser).raw_buffer.last {
+ return OK;
+ }
+ if (*parser).unread >= length {
+ return OK;
+ }
+ if (*parser).encoding == YAML_ANY_ENCODING {
+ if yaml_parser_determine_encoding(parser).fail {
+ return FAIL;
+ }
+ }
+ if (*parser).buffer.start < (*parser).buffer.pointer
+ && (*parser).buffer.pointer < (*parser).buffer.last
+ {
+ let size: size_t = (*parser)
+ .buffer
+ .last
+ .c_offset_from((*parser).buffer.pointer) as libc::c_long
+ as size_t;
+ memmove(
+ (*parser).buffer.start as *mut libc::c_void,
+ (*parser).buffer.pointer as *const libc::c_void,
+ size,
+ );
+ let fresh10 = addr_of_mut!((*parser).buffer.pointer);
+ *fresh10 = (*parser).buffer.start;
+ let fresh11 = addr_of_mut!((*parser).buffer.last);
+ *fresh11 = (*parser).buffer.start.wrapping_offset(size as isize);
+ } else if (*parser).buffer.pointer == (*parser).buffer.last {
+ let fresh12 = addr_of_mut!((*parser).buffer.pointer);
+ *fresh12 = (*parser).buffer.start;
+ let fresh13 = addr_of_mut!((*parser).buffer.last);
+ *fresh13 = (*parser).buffer.start;
+ }
+ while (*parser).unread < length {
+ if !first || (*parser).raw_buffer.pointer == (*parser).raw_buffer.last {
+ if yaml_parser_update_raw_buffer(parser).fail {
+ return FAIL;
+ }
+ }
+ first = false;
+ while (*parser).raw_buffer.pointer != (*parser).raw_buffer.last {
+ let mut value: libc::c_uint = 0;
+ let value2: libc::c_uint;
+ let mut incomplete = false;
+ let mut octet: libc::c_uchar;
+ let mut width: libc::c_uint = 0;
+ let low: libc::c_int;
+ let high: libc::c_int;
+ let mut k: size_t;
+ let raw_unread: size_t = (*parser)
+ .raw_buffer
+ .last
+ .c_offset_from((*parser).raw_buffer.pointer)
+ as libc::c_long as size_t;
+ match (*parser).encoding {
+ YAML_UTF8_ENCODING => {
+ octet = *(*parser).raw_buffer.pointer;
+ width = if octet & 0x80 == 0 {
+ 1
+ } else if octet & 0xE0 == 0xC0 {
+ 2
+ } else if octet & 0xF0 == 0xE0 {
+ 3
+ } else if octet & 0xF8 == 0xF0 {
+ 4
+ } else {
+ 0
+ } as libc::c_uint;
+ if width == 0 {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"invalid leading UTF-8 octet\0" as *const u8 as *const libc::c_char,
+ (*parser).offset,
+ octet as libc::c_int,
+ );
+ }
+ if width as libc::c_ulong > raw_unread {
+ if (*parser).eof {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"incomplete UTF-8 octet sequence\0" as *const u8
+ as *const libc::c_char,
+ (*parser).offset,
+ -1,
+ );
+ }
+ incomplete = true;
+ } else {
+ value = if octet & 0x80 == 0 {
+ octet & 0x7F
+ } else if octet & 0xE0 == 0xC0 {
+ octet & 0x1F
+ } else if octet & 0xF0 == 0xE0 {
+ octet & 0xF
+ } else if octet & 0xF8 == 0xF0 {
+ octet & 0x7
+ } else {
+ 0
+ } as libc::c_uint;
+ k = 1_u64;
+ while k < width as libc::c_ulong {
+ octet = *(*parser).raw_buffer.pointer.wrapping_offset(k as isize);
+ if octet & 0xC0 != 0x80 {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"invalid trailing UTF-8 octet\0" as *const u8
+ as *const libc::c_char,
+ (*parser).offset.wrapping_add(k),
+ octet as libc::c_int,
+ );
+ }
+ value = (value << 6).wrapping_add((octet & 0x3F) as libc::c_uint);
+ k = k.wrapping_add(1);
+ }
+ if !(width == 1
+ || width == 2 && value >= 0x80
+ || width == 3 && value >= 0x800
+ || width == 4 && value >= 0x10000)
+ {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"invalid length of a UTF-8 sequence\0" as *const u8
+ as *const libc::c_char,
+ (*parser).offset,
+ -1,
+ );
+ }
+ if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"invalid Unicode character\0" as *const u8 as *const libc::c_char,
+ (*parser).offset,
+ value as libc::c_int,
+ );
+ }
+ }
+ }
+ YAML_UTF16LE_ENCODING | YAML_UTF16BE_ENCODING => {
+ low = if (*parser).encoding == YAML_UTF16LE_ENCODING {
+ 0
+ } else {
+ 1
+ };
+ high = if (*parser).encoding == YAML_UTF16LE_ENCODING {
+ 1
+ } else {
+ 0
+ };
+ if raw_unread < 2_u64 {
+ if (*parser).eof {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"incomplete UTF-16 character\0" as *const u8
+ as *const libc::c_char,
+ (*parser).offset,
+ -1,
+ );
+ }
+ incomplete = true;
+ } else {
+ value = (*(*parser).raw_buffer.pointer.wrapping_offset(low as isize)
+ as libc::c_int
+ + ((*(*parser).raw_buffer.pointer.wrapping_offset(high as isize)
+ as libc::c_int)
+ << 8)) as libc::c_uint;
+ if value & 0xFC00 == 0xDC00 {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"unexpected low surrogate area\0" as *const u8
+ as *const libc::c_char,
+ (*parser).offset,
+ value as libc::c_int,
+ );
+ }
+ if value & 0xFC00 == 0xD800 {
+ width = 4;
+ if raw_unread < 4_u64 {
+ if (*parser).eof {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"incomplete UTF-16 surrogate pair\0" as *const u8
+ as *const libc::c_char,
+ (*parser).offset,
+ -1,
+ );
+ }
+ incomplete = true;
+ } else {
+ value2 = (*(*parser)
+ .raw_buffer
+ .pointer
+ .wrapping_offset((low + 2) as isize)
+ as libc::c_int
+ + ((*(*parser)
+ .raw_buffer
+ .pointer
+ .wrapping_offset((high + 2) as isize)
+ as libc::c_int)
+ << 8))
+ as libc::c_uint;
+ if value2 & 0xFC00 != 0xDC00 {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"expected low surrogate area\0" as *const u8
+ as *const libc::c_char,
+ (*parser).offset.wrapping_add(2_u64),
+ value2 as libc::c_int,
+ );
+ }
+ value = 0x10000_u32
+ .wrapping_add((value & 0x3FF) << 10)
+ .wrapping_add(value2 & 0x3FF);
+ }
+ } else {
+ width = 2;
+ }
+ }
+ }
+ _ => {}
+ }
+ if incomplete {
+ break;
+ }
+ if !(value == 0x9
+ || value == 0xA
+ || value == 0xD
+ || value >= 0x20 && value <= 0x7E
+ || value == 0x85
+ || value >= 0xA0 && value <= 0xD7FF
+ || value >= 0xE000 && value <= 0xFFFD
+ || value >= 0x10000 && value <= 0x10FFFF)
+ {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"control characters are not allowed\0" as *const u8 as *const libc::c_char,
+ (*parser).offset,
+ value as libc::c_int,
+ );
+ }
+ let fresh14 = addr_of_mut!((*parser).raw_buffer.pointer);
+ *fresh14 = (*fresh14).wrapping_offset(width as isize);
+ let fresh15 = addr_of_mut!((*parser).offset);
+ *fresh15 = (*fresh15 as libc::c_ulong).wrapping_add(width as libc::c_ulong) as size_t
+ as size_t;
+ if value <= 0x7F {
+ let fresh16 = addr_of_mut!((*parser).buffer.last);
+ let fresh17 = *fresh16;
+ *fresh16 = (*fresh16).wrapping_offset(1);
+ *fresh17 = value as yaml_char_t;
+ } else if value <= 0x7FF {
+ let fresh18 = addr_of_mut!((*parser).buffer.last);
+ let fresh19 = *fresh18;
+ *fresh18 = (*fresh18).wrapping_offset(1);
+ *fresh19 = 0xC0_u32.wrapping_add(value >> 6) as yaml_char_t;
+ let fresh20 = addr_of_mut!((*parser).buffer.last);
+ let fresh21 = *fresh20;
+ *fresh20 = (*fresh20).wrapping_offset(1);
+ *fresh21 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+ } else if value <= 0xFFFF {
+ let fresh22 = addr_of_mut!((*parser).buffer.last);
+ let fresh23 = *fresh22;
+ *fresh22 = (*fresh22).wrapping_offset(1);
+ *fresh23 = 0xE0_u32.wrapping_add(value >> 12) as yaml_char_t;
+ let fresh24 = addr_of_mut!((*parser).buffer.last);
+ let fresh25 = *fresh24;
+ *fresh24 = (*fresh24).wrapping_offset(1);
+ *fresh25 = 0x80_u32.wrapping_add(value >> 6 & 0x3F) as yaml_char_t;
+ let fresh26 = addr_of_mut!((*parser).buffer.last);
+ let fresh27 = *fresh26;
+ *fresh26 = (*fresh26).wrapping_offset(1);
+ *fresh27 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+ } else {
+ let fresh28 = addr_of_mut!((*parser).buffer.last);
+ let fresh29 = *fresh28;
+ *fresh28 = (*fresh28).wrapping_offset(1);
+ *fresh29 = 0xF0_u32.wrapping_add(value >> 18) as yaml_char_t;
+ let fresh30 = addr_of_mut!((*parser).buffer.last);
+ let fresh31 = *fresh30;
+ *fresh30 = (*fresh30).wrapping_offset(1);
+ *fresh31 = 0x80_u32.wrapping_add(value >> 12 & 0x3F) as yaml_char_t;
+ let fresh32 = addr_of_mut!((*parser).buffer.last);
+ let fresh33 = *fresh32;
+ *fresh32 = (*fresh32).wrapping_offset(1);
+ *fresh33 = 0x80_u32.wrapping_add(value >> 6 & 0x3F) as yaml_char_t;
+ let fresh34 = addr_of_mut!((*parser).buffer.last);
+ let fresh35 = *fresh34;
+ *fresh34 = (*fresh34).wrapping_offset(1);
+ *fresh35 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+ }
+ let fresh36 = addr_of_mut!((*parser).unread);
+ *fresh36 = (*fresh36).wrapping_add(1);
+ }
+ if (*parser).eof {
+ let fresh37 = addr_of_mut!((*parser).buffer.last);
+ let fresh38 = *fresh37;
+ *fresh37 = (*fresh37).wrapping_offset(1);
+ *fresh38 = b'\0';
+ let fresh39 = addr_of_mut!((*parser).unread);
+ *fresh39 = (*fresh39).wrapping_add(1);
+ return OK;
+ }
+ }
+ if (*parser).offset >= (!0_u64).wrapping_div(2_u64) {
+ return yaml_parser_set_reader_error(
+ parser,
+ b"input is too long\0" as *const u8 as *const libc::c_char,
+ (*parser).offset,
+ -1,
+ );
+ }
+ OK
+}
diff --git a/src/scanner.rs b/src/scanner.rs
new file mode 100644
index 0000000..175719c
--- /dev/null
+++ b/src/scanner.rs
@@ -0,0 +1,2663 @@
+use crate::api::{
+ yaml_free, yaml_malloc, yaml_queue_extend, yaml_stack_extend, yaml_string_extend,
+ yaml_string_join,
+};
+use crate::externs::{memcpy, memmove, memset, strcmp, strlen};
+use crate::reader::yaml_parser_update_buffer;
+use crate::success::{Success, FAIL, OK};
+use crate::yaml::{ptrdiff_t, size_t, yaml_char_t, yaml_string_t, NULL_STRING};
+use crate::{
+ libc, yaml_mark_t, yaml_parser_t, yaml_simple_key_t, yaml_token_t, yaml_token_type_t,
+ PointerExt, YAML_ALIAS_TOKEN, YAML_ANCHOR_TOKEN, YAML_BLOCK_END_TOKEN, YAML_BLOCK_ENTRY_TOKEN,
+ YAML_BLOCK_MAPPING_START_TOKEN, YAML_BLOCK_SEQUENCE_START_TOKEN, YAML_DOCUMENT_END_TOKEN,
+ YAML_DOCUMENT_START_TOKEN, YAML_DOUBLE_QUOTED_SCALAR_STYLE, YAML_FLOW_ENTRY_TOKEN,
+ YAML_FLOW_MAPPING_END_TOKEN, YAML_FLOW_MAPPING_START_TOKEN, YAML_FLOW_SEQUENCE_END_TOKEN,
+ YAML_FLOW_SEQUENCE_START_TOKEN, YAML_FOLDED_SCALAR_STYLE, YAML_KEY_TOKEN,
+ YAML_LITERAL_SCALAR_STYLE, YAML_MEMORY_ERROR, YAML_NO_ERROR, YAML_PLAIN_SCALAR_STYLE,
+ YAML_SCALAR_TOKEN, YAML_SCANNER_ERROR, YAML_SINGLE_QUOTED_SCALAR_STYLE, YAML_STREAM_END_TOKEN,
+ YAML_STREAM_START_TOKEN, YAML_TAG_DIRECTIVE_TOKEN, YAML_TAG_TOKEN, YAML_VALUE_TOKEN,
+ YAML_VERSION_DIRECTIVE_TOKEN,
+};
+use core::mem::{size_of, MaybeUninit};
+use core::ptr::{self, addr_of_mut};
+
+unsafe fn CACHE(parser: *mut yaml_parser_t, length: size_t) -> Success {
+ if (*parser).unread >= length {
+ OK
+ } else {
+ yaml_parser_update_buffer(parser, length)
+ }
+}
+
+unsafe fn SKIP(parser: *mut yaml_parser_t) {
+ let width = WIDTH!((*parser).buffer);
+ (*parser).mark.index = (*parser).mark.index.wrapping_add(width as u64);
+ (*parser).mark.column = (*parser).mark.column.wrapping_add(1);
+ (*parser).unread = (*parser).unread.wrapping_sub(1);
+ (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(width as isize);
+}
+
+unsafe fn SKIP_LINE(parser: *mut yaml_parser_t) {
+ if IS_CRLF!((*parser).buffer) {
+ (*parser).mark.index = (*parser).mark.index.wrapping_add(2);
+ (*parser).mark.column = 0;
+ (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+ (*parser).unread = (*parser).unread.wrapping_sub(2);
+ (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(2);
+ } else if IS_BREAK!((*parser).buffer) {
+ let width = WIDTH!((*parser).buffer);
+ (*parser).mark.index = (*parser).mark.index.wrapping_add(width as u64);
+ (*parser).mark.column = 0;
+ (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+ (*parser).unread = (*parser).unread.wrapping_sub(1);
+ (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(width as isize);
+ };
+}
+
+unsafe fn READ(parser: *mut yaml_parser_t, string: *mut yaml_string_t) {
+ STRING_EXTEND!(*string);
+ let width = WIDTH!((*parser).buffer);
+ COPY!(*string, (*parser).buffer);
+ (*parser).mark.index = (*parser).mark.index.wrapping_add(width as u64);
+ (*parser).mark.column = (*parser).mark.column.wrapping_add(1);
+ (*parser).unread = (*parser).unread.wrapping_sub(1);
+}
+
+unsafe fn READ_LINE(parser: *mut yaml_parser_t, string: *mut yaml_string_t) {
+ STRING_EXTEND!(*string);
+ if CHECK_AT!((*parser).buffer, b'\r', 0) && CHECK_AT!((*parser).buffer, b'\n', 1) {
+ *(*string).pointer = b'\n';
+ (*string).pointer = (*string).pointer.wrapping_offset(1);
+ (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(2);
+ (*parser).mark.index = (*parser).mark.index.wrapping_add(2);
+ (*parser).mark.column = 0;
+ (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+ (*parser).unread = (*parser).unread.wrapping_sub(2);
+ } else if CHECK_AT!((*parser).buffer, b'\r', 0) || CHECK_AT!((*parser).buffer, b'\n', 0) {
+ *(*string).pointer = b'\n';
+ (*string).pointer = (*string).pointer.wrapping_offset(1);
+ (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(1);
+ (*parser).mark.index = (*parser).mark.index.wrapping_add(1);
+ (*parser).mark.column = 0;
+ (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+ (*parser).unread = (*parser).unread.wrapping_sub(1);
+ } else if CHECK_AT!((*parser).buffer, b'\xC2', 0) && CHECK_AT!((*parser).buffer, b'\x85', 1) {
+ *(*string).pointer = b'\n';
+ (*string).pointer = (*string).pointer.wrapping_offset(1);
+ (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(2);
+ (*parser).mark.index = (*parser).mark.index.wrapping_add(2);
+ (*parser).mark.column = 0;
+ (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+ (*parser).unread = (*parser).unread.wrapping_sub(1);
+ } else if CHECK_AT!((*parser).buffer, b'\xE2', 0)
+ && CHECK_AT!((*parser).buffer, b'\x80', 1)
+ && (CHECK_AT!((*parser).buffer, b'\xA8', 2) || CHECK_AT!((*parser).buffer, b'\xA9', 2))
+ {
+ *(*string).pointer = *(*parser).buffer.pointer;
+ (*string).pointer = (*string).pointer.wrapping_offset(1);
+ (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(1);
+ *(*string).pointer = *(*parser).buffer.pointer;
+ (*string).pointer = (*string).pointer.wrapping_offset(1);
+ (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(1);
+ *(*string).pointer = *(*parser).buffer.pointer;
+ (*string).pointer = (*string).pointer.wrapping_offset(1);
+ (*parser).buffer.pointer = (*parser).buffer.pointer.wrapping_offset(1);
+ (*parser).mark.index = (*parser).mark.index.wrapping_add(3);
+ (*parser).mark.column = 0;
+ (*parser).mark.line = (*parser).mark.line.wrapping_add(1);
+ (*parser).unread = (*parser).unread.wrapping_sub(1);
+ };
+}
+
+macro_rules! READ {
+ ($parser:expr, $string:expr) => {
+ READ($parser, addr_of_mut!($string))
+ };
+}
+
+macro_rules! READ_LINE {
+ ($parser:expr, $string:expr) => {
+ READ_LINE($parser, addr_of_mut!($string))
+ };
+}
+
+/// Scan the input stream and produce the next token.
+///
+/// Call the function subsequently to produce a sequence of tokens corresponding
+/// to the input stream. The initial token has the type YAML_STREAM_START_TOKEN
+/// while the ending token has the type YAML_STREAM_END_TOKEN.
+///
+/// An application is responsible for freeing any buffers associated with the
+/// produced token object using the yaml_token_delete function.
+///
+/// An application must not alternate the calls of yaml_parser_scan() with the
+/// calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break
+/// the parser.
+pub unsafe fn yaml_parser_scan(parser: *mut yaml_parser_t, token: *mut yaml_token_t) -> Success {
+ __assert!(!parser.is_null());
+ __assert!(!token.is_null());
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ if (*parser).stream_end_produced || (*parser).error != YAML_NO_ERROR {
+ return OK;
+ }
+ if !(*parser).token_available {
+ if yaml_parser_fetch_more_tokens(parser).fail {
+ return FAIL;
+ }
+ }
+ *token = DEQUEUE!((*parser).tokens);
+ (*parser).token_available = false;
+ let fresh2 = addr_of_mut!((*parser).tokens_parsed);
+ *fresh2 = (*fresh2).wrapping_add(1);
+ if (*token).type_ == YAML_STREAM_END_TOKEN {
+ (*parser).stream_end_produced = true;
+ }
+ OK
+}
+
+unsafe fn yaml_parser_set_scanner_error(
+ parser: *mut yaml_parser_t,
+ context: *const libc::c_char,
+ context_mark: yaml_mark_t,
+ problem: *const libc::c_char,
+) {
+ (*parser).error = YAML_SCANNER_ERROR;
+ let fresh3 = addr_of_mut!((*parser).context);
+ *fresh3 = context;
+ (*parser).context_mark = context_mark;
+ let fresh4 = addr_of_mut!((*parser).problem);
+ *fresh4 = problem;
+ (*parser).problem_mark = (*parser).mark;
+}
+
+pub(crate) unsafe fn yaml_parser_fetch_more_tokens(parser: *mut yaml_parser_t) -> Success {
+ let mut need_more_tokens;
+ loop {
+ need_more_tokens = false;
+ if (*parser).tokens.head == (*parser).tokens.tail {
+ need_more_tokens = true;
+ } else {
+ let mut simple_key: *mut yaml_simple_key_t;
+ if yaml_parser_stale_simple_keys(parser).fail {
+ return FAIL;
+ }
+ simple_key = (*parser).simple_keys.start;
+ while simple_key != (*parser).simple_keys.top {
+ if (*simple_key).possible && (*simple_key).token_number == (*parser).tokens_parsed {
+ need_more_tokens = true;
+ break;
+ } else {
+ simple_key = simple_key.wrapping_offset(1);
+ }
+ }
+ }
+ if !need_more_tokens {
+ break;
+ }
+ if yaml_parser_fetch_next_token(parser).fail {
+ return FAIL;
+ }
+ }
+ (*parser).token_available = true;
+ OK
+}
+
+unsafe fn yaml_parser_fetch_next_token(parser: *mut yaml_parser_t) -> Success {
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ if !(*parser).stream_start_produced {
+ yaml_parser_fetch_stream_start(parser);
+ return OK;
+ }
+ if yaml_parser_scan_to_next_token(parser).fail {
+ return FAIL;
+ }
+ if yaml_parser_stale_simple_keys(parser).fail {
+ return FAIL;
+ }
+ yaml_parser_unroll_indent(parser, (*parser).mark.column as ptrdiff_t);
+ if CACHE(parser, 4_u64).fail {
+ return FAIL;
+ }
+ if IS_Z!((*parser).buffer) {
+ return yaml_parser_fetch_stream_end(parser);
+ }
+ if (*parser).mark.column == 0_u64 && CHECK!((*parser).buffer, b'%') {
+ return yaml_parser_fetch_directive(parser);
+ }
+ if (*parser).mark.column == 0_u64
+ && CHECK_AT!((*parser).buffer, b'-', 0)
+ && CHECK_AT!((*parser).buffer, b'-', 1)
+ && CHECK_AT!((*parser).buffer, b'-', 2)
+ && IS_BLANKZ_AT!((*parser).buffer, 3)
+ {
+ return yaml_parser_fetch_document_indicator(parser, YAML_DOCUMENT_START_TOKEN);
+ }
+ if (*parser).mark.column == 0_u64
+ && CHECK_AT!((*parser).buffer, b'.', 0)
+ && CHECK_AT!((*parser).buffer, b'.', 1)
+ && CHECK_AT!((*parser).buffer, b'.', 2)
+ && IS_BLANKZ_AT!((*parser).buffer, 3)
+ {
+ return yaml_parser_fetch_document_indicator(parser, YAML_DOCUMENT_END_TOKEN);
+ }
+ if CHECK!((*parser).buffer, b'[') {
+ return yaml_parser_fetch_flow_collection_start(parser, YAML_FLOW_SEQUENCE_START_TOKEN);
+ }
+ if CHECK!((*parser).buffer, b'{') {
+ return yaml_parser_fetch_flow_collection_start(parser, YAML_FLOW_MAPPING_START_TOKEN);
+ }
+ if CHECK!((*parser).buffer, b']') {
+ return yaml_parser_fetch_flow_collection_end(parser, YAML_FLOW_SEQUENCE_END_TOKEN);
+ }
+ if CHECK!((*parser).buffer, b'}') {
+ return yaml_parser_fetch_flow_collection_end(parser, YAML_FLOW_MAPPING_END_TOKEN);
+ }
+ if CHECK!((*parser).buffer, b',') {
+ return yaml_parser_fetch_flow_entry(parser);
+ }
+ if CHECK!((*parser).buffer, b'-') && IS_BLANKZ_AT!((*parser).buffer, 1) {
+ return yaml_parser_fetch_block_entry(parser);
+ }
+ if CHECK!((*parser).buffer, b'?')
+ && ((*parser).flow_level != 0 || IS_BLANKZ_AT!((*parser).buffer, 1))
+ {
+ return yaml_parser_fetch_key(parser);
+ }
+ if CHECK!((*parser).buffer, b':')
+ && ((*parser).flow_level != 0 || IS_BLANKZ_AT!((*parser).buffer, 1))
+ {
+ return yaml_parser_fetch_value(parser);
+ }
+ if CHECK!((*parser).buffer, b'*') {
+ return yaml_parser_fetch_anchor(parser, YAML_ALIAS_TOKEN);
+ }
+ if CHECK!((*parser).buffer, b'&') {
+ return yaml_parser_fetch_anchor(parser, YAML_ANCHOR_TOKEN);
+ }
+ if CHECK!((*parser).buffer, b'!') {
+ return yaml_parser_fetch_tag(parser);
+ }
+ if CHECK!((*parser).buffer, b'|') && (*parser).flow_level == 0 {
+ return yaml_parser_fetch_block_scalar(parser, true);
+ }
+ if CHECK!((*parser).buffer, b'>') && (*parser).flow_level == 0 {
+ return yaml_parser_fetch_block_scalar(parser, false);
+ }
+ if CHECK!((*parser).buffer, b'\'') {
+ return yaml_parser_fetch_flow_scalar(parser, true);
+ }
+ if CHECK!((*parser).buffer, b'"') {
+ return yaml_parser_fetch_flow_scalar(parser, false);
+ }
+ if !(IS_BLANKZ!((*parser).buffer)
+ || CHECK!((*parser).buffer, b'-')
+ || CHECK!((*parser).buffer, b'?')
+ || CHECK!((*parser).buffer, b':')
+ || CHECK!((*parser).buffer, b',')
+ || CHECK!((*parser).buffer, b'[')
+ || CHECK!((*parser).buffer, b']')
+ || CHECK!((*parser).buffer, b'{')
+ || CHECK!((*parser).buffer, b'}')
+ || CHECK!((*parser).buffer, b'#')
+ || CHECK!((*parser).buffer, b'&')
+ || CHECK!((*parser).buffer, b'*')
+ || CHECK!((*parser).buffer, b'!')
+ || CHECK!((*parser).buffer, b'|')
+ || CHECK!((*parser).buffer, b'>')
+ || CHECK!((*parser).buffer, b'\'')
+ || CHECK!((*parser).buffer, b'"')
+ || CHECK!((*parser).buffer, b'%')
+ || CHECK!((*parser).buffer, b'@')
+ || CHECK!((*parser).buffer, b'`'))
+ || CHECK!((*parser).buffer, b'-') && !IS_BLANK_AT!((*parser).buffer, 1)
+ || (*parser).flow_level == 0
+ && (CHECK!((*parser).buffer, b'?') || CHECK!((*parser).buffer, b':'))
+ && !IS_BLANKZ_AT!((*parser).buffer, 1)
+ {
+ return yaml_parser_fetch_plain_scalar(parser);
+ }
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning for the next token\0" as *const u8 as *const libc::c_char,
+ (*parser).mark,
+ b"found character that cannot start any token\0" as *const u8 as *const libc::c_char,
+ );
+ FAIL
+}
+
+unsafe fn yaml_parser_stale_simple_keys(parser: *mut yaml_parser_t) -> Success {
+ let mut simple_key: *mut yaml_simple_key_t;
+ simple_key = (*parser).simple_keys.start;
+ while simple_key != (*parser).simple_keys.top {
+ if (*simple_key).possible
+ && ((*simple_key).mark.line < (*parser).mark.line
+ || (*simple_key).mark.index.wrapping_add(1024_u64) < (*parser).mark.index)
+ {
+ if (*simple_key).required {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a simple key\0" as *const u8 as *const libc::c_char,
+ (*simple_key).mark,
+ b"could not find expected ':'\0" as *const u8 as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ (*simple_key).possible = false;
+ }
+ simple_key = simple_key.wrapping_offset(1);
+ }
+ OK
+}
+
+unsafe fn yaml_parser_save_simple_key(parser: *mut yaml_parser_t) -> Success {
+ let required = (*parser).flow_level == 0
+ && (*parser).indent as libc::c_long == (*parser).mark.column as ptrdiff_t;
+ if (*parser).simple_key_allowed {
+ let simple_key = yaml_simple_key_t {
+ possible: true,
+ required,
+ token_number: (*parser)
+ .tokens_parsed
+ .wrapping_add((*parser).tokens.tail.c_offset_from((*parser).tokens.head)
+ as libc::c_long as libc::c_ulong),
+ mark: (*parser).mark,
+ };
+ if yaml_parser_remove_simple_key(parser).fail {
+ return FAIL;
+ }
+ *(*parser).simple_keys.top.wrapping_offset(-1_isize) = simple_key;
+ }
+ OK
+}
+
+unsafe fn yaml_parser_remove_simple_key(parser: *mut yaml_parser_t) -> Success {
+ let simple_key: *mut yaml_simple_key_t = (*parser).simple_keys.top.wrapping_offset(-1_isize);
+ if (*simple_key).possible {
+ if (*simple_key).required {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a simple key\0" as *const u8 as *const libc::c_char,
+ (*simple_key).mark,
+ b"could not find expected ':'\0" as *const u8 as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ }
+ (*simple_key).possible = false;
+ OK
+}
+
+unsafe fn yaml_parser_increase_flow_level(parser: *mut yaml_parser_t) -> Success {
+ let empty_simple_key = yaml_simple_key_t {
+ possible: false,
+ required: false,
+ token_number: 0_u64,
+ mark: yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ },
+ };
+ PUSH!((*parser).simple_keys, empty_simple_key);
+ if (*parser).flow_level == libc::c_int::MAX {
+ (*parser).error = YAML_MEMORY_ERROR;
+ return FAIL;
+ }
+ let fresh7 = addr_of_mut!((*parser).flow_level);
+ *fresh7 += 1;
+ OK
+}
+
+unsafe fn yaml_parser_decrease_flow_level(parser: *mut yaml_parser_t) {
+ if (*parser).flow_level != 0 {
+ let fresh8 = addr_of_mut!((*parser).flow_level);
+ *fresh8 -= 1;
+ let _ = POP!((*parser).simple_keys);
+ }
+}
+
+unsafe fn yaml_parser_roll_indent(
+ parser: *mut yaml_parser_t,
+ column: ptrdiff_t,
+ number: ptrdiff_t,
+ type_: yaml_token_type_t,
+ mark: yaml_mark_t,
+) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if (*parser).flow_level != 0 {
+ return OK;
+ }
+ if ((*parser).indent as libc::c_long) < column {
+ PUSH!((*parser).indents, (*parser).indent);
+ if column > ptrdiff_t::from(libc::c_int::MAX) {
+ (*parser).error = YAML_MEMORY_ERROR;
+ return FAIL;
+ }
+ (*parser).indent = column as libc::c_int;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = type_;
+ (*token).start_mark = mark;
+ (*token).end_mark = mark;
+ if number == -1_i64 {
+ ENQUEUE!((*parser).tokens, *token);
+ } else {
+ QUEUE_INSERT!(
+ (*parser).tokens,
+ (number as libc::c_ulong).wrapping_sub((*parser).tokens_parsed),
+ *token
+ );
+ }
+ }
+ OK
+}
+
+unsafe fn yaml_parser_unroll_indent(parser: *mut yaml_parser_t, column: ptrdiff_t) {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if (*parser).flow_level != 0 {
+ return;
+ }
+ while (*parser).indent as libc::c_long > column {
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_BLOCK_END_TOKEN;
+ (*token).start_mark = (*parser).mark;
+ (*token).end_mark = (*parser).mark;
+ ENQUEUE!((*parser).tokens, *token);
+ (*parser).indent = POP!((*parser).indents);
+ }
+}
+
+unsafe fn yaml_parser_fetch_stream_start(parser: *mut yaml_parser_t) {
+ let simple_key = yaml_simple_key_t {
+ possible: false,
+ required: false,
+ token_number: 0_u64,
+ mark: yaml_mark_t {
+ index: 0_u64,
+ line: 0_u64,
+ column: 0_u64,
+ },
+ };
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ (*parser).indent = -1;
+ PUSH!((*parser).simple_keys, simple_key);
+ (*parser).simple_key_allowed = true;
+ (*parser).stream_start_produced = true;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_STREAM_START_TOKEN;
+ (*token).start_mark = (*parser).mark;
+ (*token).end_mark = (*parser).mark;
+ (*token).data.stream_start.encoding = (*parser).encoding;
+ ENQUEUE!((*parser).tokens, *token);
+}
+
+unsafe fn yaml_parser_fetch_stream_end(parser: *mut yaml_parser_t) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if (*parser).mark.column != 0_u64 {
+ (*parser).mark.column = 0_u64;
+ let fresh22 = addr_of_mut!((*parser).mark.line);
+ *fresh22 = (*fresh22).wrapping_add(1);
+ }
+ yaml_parser_unroll_indent(parser, -1_i64);
+ if yaml_parser_remove_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = false;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_STREAM_END_TOKEN;
+ (*token).start_mark = (*parser).mark;
+ (*token).end_mark = (*parser).mark;
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_directive(parser: *mut yaml_parser_t) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ yaml_parser_unroll_indent(parser, -1_i64);
+ if yaml_parser_remove_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = false;
+ if yaml_parser_scan_directive(parser, token).fail {
+ return FAIL;
+ }
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_document_indicator(
+ parser: *mut yaml_parser_t,
+ type_: yaml_token_type_t,
+) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ yaml_parser_unroll_indent(parser, -1_i64);
+ if yaml_parser_remove_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = false;
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ SKIP(parser);
+ SKIP(parser);
+ let end_mark: yaml_mark_t = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = type_;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_flow_collection_start(
+ parser: *mut yaml_parser_t,
+ type_: yaml_token_type_t,
+) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if yaml_parser_save_simple_key(parser).fail {
+ return FAIL;
+ }
+ if yaml_parser_increase_flow_level(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = true;
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ let end_mark: yaml_mark_t = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = type_;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_flow_collection_end(
+ parser: *mut yaml_parser_t,
+ type_: yaml_token_type_t,
+) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if yaml_parser_remove_simple_key(parser).fail {
+ return FAIL;
+ }
+ yaml_parser_decrease_flow_level(parser);
+ (*parser).simple_key_allowed = false;
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ let end_mark: yaml_mark_t = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = type_;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_flow_entry(parser: *mut yaml_parser_t) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if yaml_parser_remove_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = true;
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ let end_mark: yaml_mark_t = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_FLOW_ENTRY_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_block_entry(parser: *mut yaml_parser_t) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if (*parser).flow_level == 0 {
+ if !(*parser).simple_key_allowed {
+ yaml_parser_set_scanner_error(
+ parser,
+ ptr::null::<libc::c_char>(),
+ (*parser).mark,
+ b"block sequence entries are not allowed in this context\0" as *const u8
+ as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ if yaml_parser_roll_indent(
+ parser,
+ (*parser).mark.column as ptrdiff_t,
+ -1_i64,
+ YAML_BLOCK_SEQUENCE_START_TOKEN,
+ (*parser).mark,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ if yaml_parser_remove_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = true;
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ let end_mark: yaml_mark_t = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_BLOCK_ENTRY_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_key(parser: *mut yaml_parser_t) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if (*parser).flow_level == 0 {
+ if !(*parser).simple_key_allowed {
+ yaml_parser_set_scanner_error(
+ parser,
+ ptr::null::<libc::c_char>(),
+ (*parser).mark,
+ b"mapping keys are not allowed in this context\0" as *const u8
+ as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ if yaml_parser_roll_indent(
+ parser,
+ (*parser).mark.column as ptrdiff_t,
+ -1_i64,
+ YAML_BLOCK_MAPPING_START_TOKEN,
+ (*parser).mark,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ if yaml_parser_remove_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = (*parser).flow_level == 0;
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ let end_mark: yaml_mark_t = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_KEY_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_value(parser: *mut yaml_parser_t) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ let simple_key: *mut yaml_simple_key_t = (*parser).simple_keys.top.wrapping_offset(-1_isize);
+ if (*simple_key).possible {
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_KEY_TOKEN;
+ (*token).start_mark = (*simple_key).mark;
+ (*token).end_mark = (*simple_key).mark;
+ QUEUE_INSERT!(
+ (*parser).tokens,
+ ((*simple_key).token_number).wrapping_sub((*parser).tokens_parsed),
+ *token
+ );
+ if yaml_parser_roll_indent(
+ parser,
+ (*simple_key).mark.column as ptrdiff_t,
+ (*simple_key).token_number as ptrdiff_t,
+ YAML_BLOCK_MAPPING_START_TOKEN,
+ (*simple_key).mark,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ (*simple_key).possible = false;
+ (*parser).simple_key_allowed = false;
+ } else {
+ if (*parser).flow_level == 0 {
+ if !(*parser).simple_key_allowed {
+ yaml_parser_set_scanner_error(
+ parser,
+ ptr::null::<libc::c_char>(),
+ (*parser).mark,
+ b"mapping values are not allowed in this context\0" as *const u8
+ as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ if yaml_parser_roll_indent(
+ parser,
+ (*parser).mark.column as ptrdiff_t,
+ -1_i64,
+ YAML_BLOCK_MAPPING_START_TOKEN,
+ (*parser).mark,
+ )
+ .fail
+ {
+ return FAIL;
+ }
+ }
+ (*parser).simple_key_allowed = (*parser).flow_level == 0;
+ }
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ let end_mark: yaml_mark_t = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_VALUE_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_anchor(
+ parser: *mut yaml_parser_t,
+ type_: yaml_token_type_t,
+) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if yaml_parser_save_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = false;
+ if yaml_parser_scan_anchor(parser, token, type_).fail {
+ return FAIL;
+ }
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_tag(parser: *mut yaml_parser_t) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if yaml_parser_save_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = false;
+ if yaml_parser_scan_tag(parser, token).fail {
+ return FAIL;
+ }
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_block_scalar(parser: *mut yaml_parser_t, literal: bool) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if yaml_parser_remove_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = true;
+ if yaml_parser_scan_block_scalar(parser, token, literal).fail {
+ return FAIL;
+ }
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_flow_scalar(parser: *mut yaml_parser_t, single: bool) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if yaml_parser_save_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = false;
+ if yaml_parser_scan_flow_scalar(parser, token, single).fail {
+ return FAIL;
+ }
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_fetch_plain_scalar(parser: *mut yaml_parser_t) -> Success {
+ let mut token = MaybeUninit::<yaml_token_t>::uninit();
+ let token = token.as_mut_ptr();
+ if yaml_parser_save_simple_key(parser).fail {
+ return FAIL;
+ }
+ (*parser).simple_key_allowed = false;
+ if yaml_parser_scan_plain_scalar(parser, token).fail {
+ return FAIL;
+ }
+ ENQUEUE!((*parser).tokens, *token);
+ OK
+}
+
+unsafe fn yaml_parser_scan_to_next_token(parser: *mut yaml_parser_t) -> Success {
+ loop {
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ if (*parser).mark.column == 0_u64 && IS_BOM!((*parser).buffer) {
+ SKIP(parser);
+ }
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ while CHECK!((*parser).buffer, b' ')
+ || ((*parser).flow_level != 0 || !(*parser).simple_key_allowed)
+ && CHECK!((*parser).buffer, b'\t')
+ {
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ }
+ if CHECK!((*parser).buffer, b'#') {
+ while !IS_BREAKZ!((*parser).buffer) {
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ }
+ }
+ if !IS_BREAK!((*parser).buffer) {
+ break;
+ }
+ if CACHE(parser, 2_u64).fail {
+ return FAIL;
+ }
+ SKIP_LINE(parser);
+ if (*parser).flow_level == 0 {
+ (*parser).simple_key_allowed = true;
+ }
+ }
+ OK
+}
+
+unsafe fn yaml_parser_scan_directive(
+ parser: *mut yaml_parser_t,
+ token: *mut yaml_token_t,
+) -> Success {
+ let mut current_block: u64;
+ let end_mark: yaml_mark_t;
+ let mut name: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut major: libc::c_int = 0;
+ let mut minor: libc::c_int = 0;
+ let mut handle: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut prefix: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ if yaml_parser_scan_directive_name(parser, start_mark, addr_of_mut!(name)).ok {
+ if strcmp(
+ name as *mut libc::c_char,
+ b"YAML\0" as *const u8 as *const libc::c_char,
+ ) == 0
+ {
+ if yaml_parser_scan_version_directive_value(
+ parser,
+ start_mark,
+ addr_of_mut!(major),
+ addr_of_mut!(minor),
+ )
+ .fail
+ {
+ current_block = 11397968426844348457;
+ } else {
+ end_mark = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_VERSION_DIRECTIVE_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ (*token).data.version_directive.major = major;
+ (*token).data.version_directive.minor = minor;
+ current_block = 17407779659766490442;
+ }
+ } else if strcmp(
+ name as *mut libc::c_char,
+ b"TAG\0" as *const u8 as *const libc::c_char,
+ ) == 0
+ {
+ if yaml_parser_scan_tag_directive_value(
+ parser,
+ start_mark,
+ addr_of_mut!(handle),
+ addr_of_mut!(prefix),
+ )
+ .fail
+ {
+ current_block = 11397968426844348457;
+ } else {
+ end_mark = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_TAG_DIRECTIVE_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ let fresh112 = addr_of_mut!((*token).data.tag_directive.handle);
+ *fresh112 = handle;
+ let fresh113 = addr_of_mut!((*token).data.tag_directive.prefix);
+ *fresh113 = prefix;
+ current_block = 17407779659766490442;
+ }
+ } else {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a directive\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found unknown directive name\0" as *const u8 as *const libc::c_char,
+ );
+ current_block = 11397968426844348457;
+ }
+ if current_block != 11397968426844348457 {
+ if CACHE(parser, 1_u64).ok {
+ loop {
+ if !IS_BLANK!((*parser).buffer) {
+ current_block = 11584701595673473500;
+ break;
+ }
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 11397968426844348457;
+ break;
+ }
+ }
+ if current_block != 11397968426844348457 {
+ if CHECK!((*parser).buffer, b'#') {
+ loop {
+ if IS_BREAKZ!((*parser).buffer) {
+ current_block = 6669252993407410313;
+ break;
+ }
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 11397968426844348457;
+ break;
+ }
+ }
+ } else {
+ current_block = 6669252993407410313;
+ }
+ if current_block != 11397968426844348457 {
+ if !IS_BREAKZ!((*parser).buffer) {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a directive\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"did not find expected comment or line break\0" as *const u8
+ as *const libc::c_char,
+ );
+ } else {
+ if IS_BREAK!((*parser).buffer) {
+ if CACHE(parser, 2_u64).fail {
+ current_block = 11397968426844348457;
+ } else {
+ SKIP_LINE(parser);
+ current_block = 652864300344834934;
+ }
+ } else {
+ current_block = 652864300344834934;
+ }
+ if current_block != 11397968426844348457 {
+ yaml_free(name as *mut libc::c_void);
+ return OK;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ yaml_free(prefix as *mut libc::c_void);
+ yaml_free(handle as *mut libc::c_void);
+ yaml_free(name as *mut libc::c_void);
+ FAIL
+}
+
+unsafe fn yaml_parser_scan_directive_name(
+ parser: *mut yaml_parser_t,
+ start_mark: yaml_mark_t,
+ name: *mut *mut yaml_char_t,
+) -> Success {
+ let current_block: u64;
+ let mut string = NULL_STRING;
+ STRING_INIT!(string);
+ if CACHE(parser, 1_u64).ok {
+ loop {
+ if !IS_ALPHA!((*parser).buffer) {
+ current_block = 10879442775620481940;
+ break;
+ }
+ READ!(parser, string);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 8318012024179131575;
+ break;
+ }
+ }
+ if current_block != 8318012024179131575 {
+ if string.start == string.pointer {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a directive\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"could not find expected directive name\0" as *const u8 as *const libc::c_char,
+ );
+ } else if !IS_BLANKZ!((*parser).buffer) {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a directive\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found unexpected non-alphabetical character\0" as *const u8
+ as *const libc::c_char,
+ );
+ } else {
+ *name = string.start;
+ return OK;
+ }
+ }
+ }
+ STRING_DEL!(string);
+ FAIL
+}
+
+unsafe fn yaml_parser_scan_version_directive_value(
+ parser: *mut yaml_parser_t,
+ start_mark: yaml_mark_t,
+ major: *mut libc::c_int,
+ minor: *mut libc::c_int,
+) -> Success {
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ while IS_BLANK!((*parser).buffer) {
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ }
+ if yaml_parser_scan_version_directive_number(parser, start_mark, major).fail {
+ return FAIL;
+ }
+ if !CHECK!((*parser).buffer, b'.') {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a %YAML directive\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"did not find expected digit or '.' character\0" as *const u8 as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ SKIP(parser);
+ yaml_parser_scan_version_directive_number(parser, start_mark, minor)
+}
+
+const MAX_NUMBER_LENGTH: u64 = 9_u64;
+
+unsafe fn yaml_parser_scan_version_directive_number(
+ parser: *mut yaml_parser_t,
+ start_mark: yaml_mark_t,
+ number: *mut libc::c_int,
+) -> Success {
+ let mut value: libc::c_int = 0;
+ let mut length: size_t = 0_u64;
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ while IS_DIGIT!((*parser).buffer) {
+ length = length.wrapping_add(1);
+ if length > MAX_NUMBER_LENGTH {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a %YAML directive\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found extremely long version number\0" as *const u8 as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ value = value * 10 + AS_DIGIT!((*parser).buffer);
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ }
+ if length == 0 {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a %YAML directive\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"did not find expected version number\0" as *const u8 as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ *number = value;
+ OK
+}
+
+unsafe fn yaml_parser_scan_tag_directive_value(
+ parser: *mut yaml_parser_t,
+ start_mark: yaml_mark_t,
+ handle: *mut *mut yaml_char_t,
+ prefix: *mut *mut yaml_char_t,
+) -> Success {
+ let mut current_block: u64;
+ let mut handle_value: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut prefix_value: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ if CACHE(parser, 1_u64).fail {
+ current_block = 5231181710497607163;
+ } else {
+ current_block = 14916268686031723178;
+ }
+ 'c_34337: loop {
+ match current_block {
+ 5231181710497607163 => {
+ yaml_free(handle_value as *mut libc::c_void);
+ yaml_free(prefix_value as *mut libc::c_void);
+ return FAIL;
+ }
+ _ => {
+ if IS_BLANK!((*parser).buffer) {
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 5231181710497607163;
+ } else {
+ current_block = 14916268686031723178;
+ }
+ } else {
+ if yaml_parser_scan_tag_handle(
+ parser,
+ true,
+ start_mark,
+ addr_of_mut!(handle_value),
+ )
+ .fail
+ {
+ current_block = 5231181710497607163;
+ continue;
+ }
+ if CACHE(parser, 1_u64).fail {
+ current_block = 5231181710497607163;
+ continue;
+ }
+ if !IS_BLANK!((*parser).buffer) {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a %TAG directive\0" as *const u8
+ as *const libc::c_char,
+ start_mark,
+ b"did not find expected whitespace\0" as *const u8
+ as *const libc::c_char,
+ );
+ current_block = 5231181710497607163;
+ } else {
+ while IS_BLANK!((*parser).buffer) {
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 5231181710497607163;
+ continue 'c_34337;
+ }
+ }
+ if yaml_parser_scan_tag_uri(
+ parser,
+ true,
+ true,
+ ptr::null_mut::<yaml_char_t>(),
+ start_mark,
+ addr_of_mut!(prefix_value),
+ )
+ .fail
+ {
+ current_block = 5231181710497607163;
+ continue;
+ }
+ if CACHE(parser, 1_u64).fail {
+ current_block = 5231181710497607163;
+ continue;
+ }
+ if !IS_BLANKZ!((*parser).buffer) {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a %TAG directive\0" as *const u8
+ as *const libc::c_char,
+ start_mark,
+ b"did not find expected whitespace or line break\0" as *const u8
+ as *const libc::c_char,
+ );
+ current_block = 5231181710497607163;
+ } else {
+ *handle = handle_value;
+ *prefix = prefix_value;
+ return OK;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+unsafe fn yaml_parser_scan_anchor(
+ parser: *mut yaml_parser_t,
+ token: *mut yaml_token_t,
+ type_: yaml_token_type_t,
+) -> Success {
+ let current_block: u64;
+ let mut length: libc::c_int = 0;
+ let end_mark: yaml_mark_t;
+ let mut string = NULL_STRING;
+ STRING_INIT!(string);
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ if CACHE(parser, 1_u64).ok {
+ loop {
+ if !IS_ALPHA!((*parser).buffer) {
+ current_block = 2868539653012386629;
+ break;
+ }
+ READ!(parser, string);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 5883759901342942623;
+ break;
+ }
+ length += 1;
+ }
+ if current_block != 5883759901342942623 {
+ end_mark = (*parser).mark;
+ if length == 0
+ || !(IS_BLANKZ!((*parser).buffer)
+ || CHECK!((*parser).buffer, b'?')
+ || CHECK!((*parser).buffer, b':')
+ || CHECK!((*parser).buffer, b',')
+ || CHECK!((*parser).buffer, b']')
+ || CHECK!((*parser).buffer, b'}')
+ || CHECK!((*parser).buffer, b'%')
+ || CHECK!((*parser).buffer, b'@')
+ || CHECK!((*parser).buffer, b'`'))
+ {
+ yaml_parser_set_scanner_error(
+ parser,
+ if type_ == YAML_ANCHOR_TOKEN {
+ b"while scanning an anchor\0" as *const u8 as *const libc::c_char
+ } else {
+ b"while scanning an alias\0" as *const u8 as *const libc::c_char
+ },
+ start_mark,
+ b"did not find expected alphabetic or numeric character\0" as *const u8
+ as *const libc::c_char,
+ );
+ } else {
+ if type_ == YAML_ANCHOR_TOKEN {
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_ANCHOR_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ let fresh220 = addr_of_mut!((*token).data.anchor.value);
+ *fresh220 = string.start;
+ } else {
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_ALIAS_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ let fresh221 = addr_of_mut!((*token).data.alias.value);
+ *fresh221 = string.start;
+ }
+ return OK;
+ }
+ }
+ }
+ STRING_DEL!(string);
+ FAIL
+}
+
+unsafe fn yaml_parser_scan_tag(parser: *mut yaml_parser_t, token: *mut yaml_token_t) -> Success {
+ let mut current_block: u64;
+ let mut handle: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let mut suffix: *mut yaml_char_t = ptr::null_mut::<yaml_char_t>();
+ let end_mark: yaml_mark_t;
+ let start_mark: yaml_mark_t = (*parser).mark;
+ if CACHE(parser, 2_u64).ok {
+ if CHECK_AT!((*parser).buffer, b'<', 1) {
+ handle = yaml_malloc(1_u64) as *mut yaml_char_t;
+ *handle = b'\0';
+ SKIP(parser);
+ SKIP(parser);
+ if yaml_parser_scan_tag_uri(
+ parser,
+ true,
+ false,
+ ptr::null_mut::<yaml_char_t>(),
+ start_mark,
+ addr_of_mut!(suffix),
+ )
+ .fail
+ {
+ current_block = 17708497480799081542;
+ } else if !CHECK!((*parser).buffer, b'>') {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a tag\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"did not find the expected '>'\0" as *const u8 as *const libc::c_char,
+ );
+ current_block = 17708497480799081542;
+ } else {
+ SKIP(parser);
+ current_block = 4488286894823169796;
+ }
+ } else if yaml_parser_scan_tag_handle(parser, false, start_mark, addr_of_mut!(handle)).fail
+ {
+ current_block = 17708497480799081542;
+ } else if *handle == b'!'
+ && *handle.wrapping_offset(1_isize) != b'\0'
+ && *handle
+ .wrapping_offset(strlen(handle as *mut libc::c_char).wrapping_sub(1_u64) as isize)
+ == b'!'
+ {
+ if yaml_parser_scan_tag_uri(
+ parser,
+ false,
+ false,
+ ptr::null_mut::<yaml_char_t>(),
+ start_mark,
+ addr_of_mut!(suffix),
+ )
+ .fail
+ {
+ current_block = 17708497480799081542;
+ } else {
+ current_block = 4488286894823169796;
+ }
+ } else if yaml_parser_scan_tag_uri(
+ parser,
+ false,
+ false,
+ handle,
+ start_mark,
+ addr_of_mut!(suffix),
+ )
+ .fail
+ {
+ current_block = 17708497480799081542;
+ } else {
+ yaml_free(handle as *mut libc::c_void);
+ handle = yaml_malloc(2_u64) as *mut yaml_char_t;
+ *handle = b'!';
+ *handle.wrapping_offset(1_isize) = b'\0';
+ if *suffix == b'\0' {
+ let tmp: *mut yaml_char_t = handle;
+ handle = suffix;
+ suffix = tmp;
+ }
+ current_block = 4488286894823169796;
+ }
+ if current_block != 17708497480799081542 {
+ if CACHE(parser, 1_u64).ok {
+ if !IS_BLANKZ!((*parser).buffer) {
+ if (*parser).flow_level == 0 || !CHECK!((*parser).buffer, b',') {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a tag\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"did not find expected whitespace or line break\0" as *const u8
+ as *const libc::c_char,
+ );
+ current_block = 17708497480799081542;
+ } else {
+ current_block = 7333393191927787629;
+ }
+ } else {
+ current_block = 7333393191927787629;
+ }
+ if current_block != 17708497480799081542 {
+ end_mark = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_TAG_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ let fresh234 = addr_of_mut!((*token).data.tag.handle);
+ *fresh234 = handle;
+ let fresh235 = addr_of_mut!((*token).data.tag.suffix);
+ *fresh235 = suffix;
+ return OK;
+ }
+ }
+ }
+ }
+ yaml_free(handle as *mut libc::c_void);
+ yaml_free(suffix as *mut libc::c_void);
+ FAIL
+}
+
+unsafe fn yaml_parser_scan_tag_handle(
+ parser: *mut yaml_parser_t,
+ directive: bool,
+ start_mark: yaml_mark_t,
+ handle: *mut *mut yaml_char_t,
+) -> Success {
+ let mut current_block: u64;
+ let mut string = NULL_STRING;
+ STRING_INIT!(string);
+ if CACHE(parser, 1_u64).ok {
+ if !CHECK!((*parser).buffer, b'!') {
+ yaml_parser_set_scanner_error(
+ parser,
+ if directive {
+ b"while scanning a tag directive\0" as *const u8 as *const libc::c_char
+ } else {
+ b"while scanning a tag\0" as *const u8 as *const libc::c_char
+ },
+ start_mark,
+ b"did not find expected '!'\0" as *const u8 as *const libc::c_char,
+ );
+ } else {
+ READ!(parser, string);
+ if CACHE(parser, 1_u64).ok {
+ loop {
+ if !IS_ALPHA!((*parser).buffer) {
+ current_block = 7651349459974463963;
+ break;
+ }
+ READ!(parser, string);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 1771849829115608806;
+ break;
+ }
+ }
+ if current_block != 1771849829115608806 {
+ if CHECK!((*parser).buffer, b'!') {
+ READ!(parser, string);
+ current_block = 5689001924483802034;
+ } else if directive
+ && !(*string.start == b'!'
+ && *string.start.wrapping_offset(1_isize) == b'\0')
+ {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while parsing a tag directive\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"did not find expected '!'\0" as *const u8 as *const libc::c_char,
+ );
+ current_block = 1771849829115608806;
+ } else {
+ current_block = 5689001924483802034;
+ }
+ if current_block != 1771849829115608806 {
+ *handle = string.start;
+ return OK;
+ }
+ }
+ }
+ }
+ }
+ STRING_DEL!(string);
+ FAIL
+}
+
+unsafe fn yaml_parser_scan_tag_uri(
+ parser: *mut yaml_parser_t,
+ uri_char: bool,
+ directive: bool,
+ head: *mut yaml_char_t,
+ start_mark: yaml_mark_t,
+ uri: *mut *mut yaml_char_t,
+) -> Success {
+ let mut current_block: u64;
+ let mut length: size_t = if !head.is_null() {
+ strlen(head as *mut libc::c_char)
+ } else {
+ 0_u64
+ };
+ let mut string = NULL_STRING;
+ STRING_INIT!(string);
+ current_block = 14916268686031723178;
+ 'c_21953: loop {
+ match current_block {
+ 15265153392498847348 => {
+ STRING_DEL!(string);
+ return FAIL;
+ }
+ _ => {
+ if string.end.c_offset_from(string.start) as libc::c_long as size_t <= length {
+ yaml_string_extend(
+ addr_of_mut!(string.start),
+ addr_of_mut!(string.pointer),
+ addr_of_mut!(string.end),
+ );
+ current_block = 14916268686031723178;
+ continue;
+ } else {
+ if length > 1_u64 {
+ memcpy(
+ string.start as *mut libc::c_void,
+ head.wrapping_offset(1_isize) as *const libc::c_void,
+ length.wrapping_sub(1_u64),
+ );
+ string.pointer = string
+ .pointer
+ .wrapping_offset(length.wrapping_sub(1_u64) as isize);
+ }
+ if CACHE(parser, 1_u64).fail {
+ current_block = 15265153392498847348;
+ continue;
+ }
+ while IS_ALPHA!((*parser).buffer)
+ || CHECK!((*parser).buffer, b';')
+ || CHECK!((*parser).buffer, b'/')
+ || CHECK!((*parser).buffer, b'?')
+ || CHECK!((*parser).buffer, b':')
+ || CHECK!((*parser).buffer, b'@')
+ || CHECK!((*parser).buffer, b'&')
+ || CHECK!((*parser).buffer, b'=')
+ || CHECK!((*parser).buffer, b'+')
+ || CHECK!((*parser).buffer, b'$')
+ || CHECK!((*parser).buffer, b'.')
+ || CHECK!((*parser).buffer, b'%')
+ || CHECK!((*parser).buffer, b'!')
+ || CHECK!((*parser).buffer, b'~')
+ || CHECK!((*parser).buffer, b'*')
+ || CHECK!((*parser).buffer, b'\'')
+ || CHECK!((*parser).buffer, b'(')
+ || CHECK!((*parser).buffer, b')')
+ || uri_char
+ && (CHECK!((*parser).buffer, b',')
+ || CHECK!((*parser).buffer, b'[')
+ || CHECK!((*parser).buffer, b']'))
+ {
+ if CHECK!((*parser).buffer, b'%') {
+ STRING_EXTEND!(string);
+ if yaml_parser_scan_uri_escapes(
+ parser,
+ directive,
+ start_mark,
+ addr_of_mut!(string),
+ )
+ .fail
+ {
+ current_block = 15265153392498847348;
+ continue 'c_21953;
+ }
+ } else {
+ READ!(parser, string);
+ }
+ length = length.wrapping_add(1);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 15265153392498847348;
+ continue 'c_21953;
+ }
+ }
+ if length == 0 {
+ STRING_EXTEND!(string);
+ yaml_parser_set_scanner_error(
+ parser,
+ if directive {
+ b"while parsing a %TAG directive\0" as *const u8
+ as *const libc::c_char
+ } else {
+ b"while parsing a tag\0" as *const u8 as *const libc::c_char
+ },
+ start_mark,
+ b"did not find expected tag URI\0" as *const u8 as *const libc::c_char,
+ );
+ current_block = 15265153392498847348;
+ } else {
+ *uri = string.start;
+ return OK;
+ }
+ }
+ }
+ }
+ }
+}
+
+unsafe fn yaml_parser_scan_uri_escapes(
+ parser: *mut yaml_parser_t,
+ directive: bool,
+ start_mark: yaml_mark_t,
+ string: *mut yaml_string_t,
+) -> Success {
+ let mut width: libc::c_int = 0;
+ loop {
+ if CACHE(parser, 3_u64).fail {
+ return FAIL;
+ }
+ if !(CHECK!((*parser).buffer, b'%')
+ && IS_HEX_AT!((*parser).buffer, 1)
+ && IS_HEX_AT!((*parser).buffer, 2))
+ {
+ yaml_parser_set_scanner_error(
+ parser,
+ if directive {
+ b"while parsing a %TAG directive\0" as *const u8 as *const libc::c_char
+ } else {
+ b"while parsing a tag\0" as *const u8 as *const libc::c_char
+ },
+ start_mark,
+ b"did not find URI escaped octet\0" as *const u8 as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ let octet: libc::c_uchar = ((AS_HEX_AT!((*parser).buffer, 1) << 4)
+ + AS_HEX_AT!((*parser).buffer, 2)) as libc::c_uchar;
+ if width == 0 {
+ width = if octet & 0x80 == 0 {
+ 1
+ } else if octet & 0xE0 == 0xC0 {
+ 2
+ } else if octet & 0xF0 == 0xE0 {
+ 3
+ } else if octet & 0xF8 == 0xF0 {
+ 4
+ } else {
+ 0
+ };
+ if width == 0 {
+ yaml_parser_set_scanner_error(
+ parser,
+ if directive {
+ b"while parsing a %TAG directive\0" as *const u8 as *const libc::c_char
+ } else {
+ b"while parsing a tag\0" as *const u8 as *const libc::c_char
+ },
+ start_mark,
+ b"found an incorrect leading UTF-8 octet\0" as *const u8 as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ } else if octet & 0xC0 != 0x80 {
+ yaml_parser_set_scanner_error(
+ parser,
+ if directive {
+ b"while parsing a %TAG directive\0" as *const u8 as *const libc::c_char
+ } else {
+ b"while parsing a tag\0" as *const u8 as *const libc::c_char
+ },
+ start_mark,
+ b"found an incorrect trailing UTF-8 octet\0" as *const u8 as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ let fresh368 = addr_of_mut!((*string).pointer);
+ let fresh369 = *fresh368;
+ *fresh368 = (*fresh368).wrapping_offset(1);
+ *fresh369 = octet;
+ SKIP(parser);
+ SKIP(parser);
+ SKIP(parser);
+ width -= 1;
+ if !(width != 0) {
+ break;
+ }
+ }
+ OK
+}
+
+unsafe fn yaml_parser_scan_block_scalar(
+ parser: *mut yaml_parser_t,
+ token: *mut yaml_token_t,
+ literal: bool,
+) -> Success {
+ let mut current_block: u64;
+ let mut end_mark: yaml_mark_t;
+ let mut string = NULL_STRING;
+ let mut leading_break = NULL_STRING;
+ let mut trailing_breaks = NULL_STRING;
+ let mut chomping: libc::c_int = 0;
+ let mut increment: libc::c_int = 0;
+ let mut indent: libc::c_int = 0;
+ let mut leading_blank: libc::c_int = 0;
+ let mut trailing_blank: libc::c_int;
+ STRING_INIT!(string);
+ STRING_INIT!(leading_break);
+ STRING_INIT!(trailing_breaks);
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ if CACHE(parser, 1_u64).ok {
+ if CHECK!((*parser).buffer, b'+') || CHECK!((*parser).buffer, b'-') {
+ chomping = if CHECK!((*parser).buffer, b'+') {
+ 1
+ } else {
+ -1
+ };
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 14984465786483313892;
+ } else if IS_DIGIT!((*parser).buffer) {
+ if CHECK!((*parser).buffer, b'0') {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a block scalar\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found an indentation indicator equal to 0\0" as *const u8
+ as *const libc::c_char,
+ );
+ current_block = 14984465786483313892;
+ } else {
+ increment = AS_DIGIT!((*parser).buffer);
+ SKIP(parser);
+ current_block = 11913429853522160501;
+ }
+ } else {
+ current_block = 11913429853522160501;
+ }
+ } else if IS_DIGIT!((*parser).buffer) {
+ if CHECK!((*parser).buffer, b'0') {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a block scalar\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found an indentation indicator equal to 0\0" as *const u8
+ as *const libc::c_char,
+ );
+ current_block = 14984465786483313892;
+ } else {
+ increment = AS_DIGIT!((*parser).buffer);
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 14984465786483313892;
+ } else {
+ if CHECK!((*parser).buffer, b'+') || CHECK!((*parser).buffer, b'-') {
+ chomping = if CHECK!((*parser).buffer, b'+') {
+ 1
+ } else {
+ -1
+ };
+ SKIP(parser);
+ }
+ current_block = 11913429853522160501;
+ }
+ }
+ } else {
+ current_block = 11913429853522160501;
+ }
+ if current_block != 14984465786483313892 {
+ if CACHE(parser, 1_u64).ok {
+ loop {
+ if !IS_BLANK!((*parser).buffer) {
+ current_block = 4090602189656566074;
+ break;
+ }
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 14984465786483313892;
+ break;
+ }
+ }
+ if current_block != 14984465786483313892 {
+ if CHECK!((*parser).buffer, b'#') {
+ loop {
+ if IS_BREAKZ!((*parser).buffer) {
+ current_block = 12997042908615822766;
+ break;
+ }
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 14984465786483313892;
+ break;
+ }
+ }
+ } else {
+ current_block = 12997042908615822766;
+ }
+ if current_block != 14984465786483313892 {
+ if !IS_BREAKZ!((*parser).buffer) {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a block scalar\0" as *const u8
+ as *const libc::c_char,
+ start_mark,
+ b"did not find expected comment or line break\0" as *const u8
+ as *const libc::c_char,
+ );
+ } else {
+ if IS_BREAK!((*parser).buffer) {
+ if CACHE(parser, 2_u64).fail {
+ current_block = 14984465786483313892;
+ } else {
+ SKIP_LINE(parser);
+ current_block = 13619784596304402172;
+ }
+ } else {
+ current_block = 13619784596304402172;
+ }
+ if current_block != 14984465786483313892 {
+ end_mark = (*parser).mark;
+ if increment != 0 {
+ indent = if (*parser).indent >= 0 {
+ (*parser).indent + increment
+ } else {
+ increment
+ };
+ }
+ if yaml_parser_scan_block_scalar_breaks(
+ parser,
+ addr_of_mut!(indent),
+ addr_of_mut!(trailing_breaks),
+ start_mark,
+ addr_of_mut!(end_mark),
+ )
+ .ok
+ {
+ if CACHE(parser, 1_u64).ok {
+ 's_281: loop {
+ if !((*parser).mark.column as libc::c_int == indent
+ && !IS_Z!((*parser).buffer))
+ {
+ current_block = 5793491756164225964;
+ break;
+ }
+ trailing_blank =
+ IS_BLANK!((*parser).buffer) as libc::c_int;
+ if !literal
+ && *leading_break.start == b'\n'
+ && leading_blank == 0
+ && trailing_blank == 0
+ {
+ if *trailing_breaks.start == b'\0' {
+ STRING_EXTEND!(string);
+ let fresh418 = string.pointer;
+ string.pointer =
+ string.pointer.wrapping_offset(1);
+ *fresh418 = b' ';
+ }
+ CLEAR!(leading_break);
+ } else {
+ JOIN!(string, leading_break);
+ CLEAR!(leading_break);
+ }
+ JOIN!(string, trailing_breaks);
+ CLEAR!(trailing_breaks);
+ leading_blank =
+ IS_BLANK!((*parser).buffer) as libc::c_int;
+ while !IS_BREAKZ!((*parser).buffer) {
+ READ!(parser, string);
+ if CACHE(parser, 1_u64).fail {
+ current_block = 14984465786483313892;
+ break 's_281;
+ }
+ }
+ if CACHE(parser, 2_u64).fail {
+ current_block = 14984465786483313892;
+ break;
+ }
+ READ_LINE!(parser, leading_break);
+ if yaml_parser_scan_block_scalar_breaks(
+ parser,
+ addr_of_mut!(indent),
+ addr_of_mut!(trailing_breaks),
+ start_mark,
+ addr_of_mut!(end_mark),
+ )
+ .fail
+ {
+ current_block = 14984465786483313892;
+ break;
+ }
+ }
+ if current_block != 14984465786483313892 {
+ if chomping != -1 {
+ JOIN!(string, leading_break);
+ current_block = 17787701279558130514;
+ } else {
+ current_block = 17787701279558130514;
+ }
+ if current_block != 14984465786483313892 {
+ if chomping == 1 {
+ JOIN!(string, trailing_breaks);
+ }
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_SCALAR_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ let fresh479 =
+ addr_of_mut!((*token).data.scalar.value);
+ *fresh479 = string.start;
+ (*token).data.scalar.length =
+ string.pointer.c_offset_from(string.start)
+ as libc::c_long
+ as size_t;
+ (*token).data.scalar.style = if literal {
+ YAML_LITERAL_SCALAR_STYLE
+ } else {
+ YAML_FOLDED_SCALAR_STYLE
+ };
+ STRING_DEL!(leading_break);
+ STRING_DEL!(trailing_breaks);
+ return OK;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ STRING_DEL!(string);
+ STRING_DEL!(leading_break);
+ STRING_DEL!(trailing_breaks);
+ FAIL
+}
+
+unsafe fn yaml_parser_scan_block_scalar_breaks(
+ parser: *mut yaml_parser_t,
+ indent: *mut libc::c_int,
+ breaks: *mut yaml_string_t,
+ start_mark: yaml_mark_t,
+ end_mark: *mut yaml_mark_t,
+) -> Success {
+ let mut max_indent: libc::c_int = 0;
+ *end_mark = (*parser).mark;
+ loop {
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ while (*indent == 0 || ((*parser).mark.column as libc::c_int) < *indent)
+ && IS_SPACE!((*parser).buffer)
+ {
+ SKIP(parser);
+ if CACHE(parser, 1_u64).fail {
+ return FAIL;
+ }
+ }
+ if (*parser).mark.column as libc::c_int > max_indent {
+ max_indent = (*parser).mark.column as libc::c_int;
+ }
+ if (*indent == 0 || ((*parser).mark.column as libc::c_int) < *indent)
+ && IS_TAB!((*parser).buffer)
+ {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a block scalar\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found a tab character where an indentation space is expected\0" as *const u8
+ as *const libc::c_char,
+ );
+ return FAIL;
+ }
+ if !IS_BREAK!((*parser).buffer) {
+ break;
+ }
+ if CACHE(parser, 2_u64).fail {
+ return FAIL;
+ }
+ READ_LINE!(parser, *breaks);
+ *end_mark = (*parser).mark;
+ }
+ if *indent == 0 {
+ *indent = max_indent;
+ if *indent < (*parser).indent + 1 {
+ *indent = (*parser).indent + 1;
+ }
+ if *indent < 1 {
+ *indent = 1;
+ }
+ }
+ OK
+}
+
+unsafe fn yaml_parser_scan_flow_scalar(
+ parser: *mut yaml_parser_t,
+ token: *mut yaml_token_t,
+ single: bool,
+) -> Success {
+ let current_block: u64;
+ let end_mark: yaml_mark_t;
+ let mut string = NULL_STRING;
+ let mut leading_break = NULL_STRING;
+ let mut trailing_breaks = NULL_STRING;
+ let mut whitespaces = NULL_STRING;
+ let mut leading_blanks;
+ STRING_INIT!(string);
+ STRING_INIT!(leading_break);
+ STRING_INIT!(trailing_breaks);
+ STRING_INIT!(whitespaces);
+ let start_mark: yaml_mark_t = (*parser).mark;
+ SKIP(parser);
+ 's_58: loop {
+ if CACHE(parser, 4_u64).fail {
+ current_block = 8114179180390253173;
+ break;
+ }
+ if (*parser).mark.column == 0_u64
+ && (CHECK_AT!((*parser).buffer, b'-', 0)
+ && CHECK_AT!((*parser).buffer, b'-', 1)
+ && CHECK_AT!((*parser).buffer, b'-', 2)
+ || CHECK_AT!((*parser).buffer, b'.', 0)
+ && CHECK_AT!((*parser).buffer, b'.', 1)
+ && CHECK_AT!((*parser).buffer, b'.', 2))
+ && IS_BLANKZ_AT!((*parser).buffer, 3)
+ {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a quoted scalar\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found unexpected document indicator\0" as *const u8 as *const libc::c_char,
+ );
+ current_block = 8114179180390253173;
+ break;
+ } else if IS_Z!((*parser).buffer) {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a quoted scalar\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found unexpected end of stream\0" as *const u8 as *const libc::c_char,
+ );
+ current_block = 8114179180390253173;
+ break;
+ } else {
+ if CACHE(parser, 2_u64).fail {
+ current_block = 8114179180390253173;
+ break;
+ }
+ leading_blanks = false;
+ while !IS_BLANKZ!((*parser).buffer) {
+ if single
+ && CHECK_AT!((*parser).buffer, b'\'', 0)
+ && CHECK_AT!((*parser).buffer, b'\'', 1)
+ {
+ STRING_EXTEND!(string);
+ let fresh521 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh521 = b'\'';
+ SKIP(parser);
+ SKIP(parser);
+ } else {
+ if CHECK!((*parser).buffer, if single { b'\'' } else { b'"' }) {
+ break;
+ }
+ if !single
+ && CHECK!((*parser).buffer, b'\\')
+ && IS_BREAK_AT!((*parser).buffer, 1)
+ {
+ if CACHE(parser, 3_u64).fail {
+ current_block = 8114179180390253173;
+ break 's_58;
+ }
+ SKIP(parser);
+ SKIP_LINE(parser);
+ leading_blanks = true;
+ break;
+ } else if !single && CHECK!((*parser).buffer, b'\\') {
+ let mut code_length: size_t = 0_u64;
+ STRING_EXTEND!(string);
+ match *(*parser).buffer.pointer.wrapping_offset(1_isize) {
+ b'0' => {
+ let fresh542 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh542 = b'\0';
+ }
+ b'a' => {
+ let fresh543 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh543 = b'\x07';
+ }
+ b'b' => {
+ let fresh544 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh544 = b'\x08';
+ }
+ b't' | b'\t' => {
+ let fresh545 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh545 = b'\t';
+ }
+ b'n' => {
+ let fresh546 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh546 = b'\n';
+ }
+ b'v' => {
+ let fresh547 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh547 = b'\x0B';
+ }
+ b'f' => {
+ let fresh548 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh548 = b'\x0C';
+ }
+ b'r' => {
+ let fresh549 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh549 = b'\r';
+ }
+ b'e' => {
+ let fresh550 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh550 = b'\x1B';
+ }
+ b' ' => {
+ let fresh551 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh551 = b' ';
+ }
+ b'"' => {
+ let fresh552 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh552 = b'"';
+ }
+ b'/' => {
+ let fresh553 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh553 = b'/';
+ }
+ b'\\' => {
+ let fresh554 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh554 = b'\\';
+ }
+ // NEL (#x85)
+ b'N' => {
+ let fresh555 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh555 = b'\xC2';
+ let fresh556 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh556 = b'\x85';
+ }
+ // #xA0
+ b'_' => {
+ let fresh557 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh557 = b'\xC2';
+ let fresh558 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh558 = b'\xA0';
+ }
+ // LS (#x2028)
+ b'L' => {
+ let fresh559 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh559 = b'\xE2';
+ let fresh560 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh560 = b'\x80';
+ let fresh561 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh561 = b'\xA8';
+ }
+ // PS (#x2029)
+ b'P' => {
+ let fresh562 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh562 = b'\xE2';
+ let fresh563 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh563 = b'\x80';
+ let fresh564 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh564 = b'\xA9';
+ }
+ b'x' => {
+ code_length = 2_u64;
+ }
+ b'u' => {
+ code_length = 4_u64;
+ }
+ b'U' => {
+ code_length = 8_u64;
+ }
+ _ => {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while parsing a quoted scalar\0" as *const u8
+ as *const libc::c_char,
+ start_mark,
+ b"found unknown escape character\0" as *const u8
+ as *const libc::c_char,
+ );
+ current_block = 8114179180390253173;
+ break 's_58;
+ }
+ }
+ SKIP(parser);
+ SKIP(parser);
+ if code_length != 0 {
+ let mut value: libc::c_uint = 0;
+ let mut k: size_t;
+ if CACHE(parser, code_length).fail {
+ current_block = 8114179180390253173;
+ break 's_58;
+ }
+ k = 0_u64;
+ while k < code_length {
+ if !IS_HEX_AT!((*parser).buffer, k as isize) {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while parsing a quoted scalar\0" as *const u8
+ as *const libc::c_char,
+ start_mark,
+ b"did not find expected hexdecimal number\0" as *const u8
+ as *const libc::c_char,
+ );
+ current_block = 8114179180390253173;
+ break 's_58;
+ } else {
+ value = (value << 4).wrapping_add(AS_HEX_AT!(
+ (*parser).buffer,
+ k as isize
+ )
+ as libc::c_uint);
+ k = k.wrapping_add(1);
+ }
+ }
+ if value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while parsing a quoted scalar\0" as *const u8
+ as *const libc::c_char,
+ start_mark,
+ b"found invalid Unicode character escape code\0" as *const u8
+ as *const libc::c_char,
+ );
+ current_block = 8114179180390253173;
+ break 's_58;
+ } else {
+ if value <= 0x7F {
+ let fresh573 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh573 = value as yaml_char_t;
+ } else if value <= 0x7FF {
+ let fresh574 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh574 = 0xC0_u32.wrapping_add(value >> 6) as yaml_char_t;
+ let fresh575 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh575 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+ } else if value <= 0xFFFF {
+ let fresh576 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh576 = 0xE0_u32.wrapping_add(value >> 12) as yaml_char_t;
+ let fresh577 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh577 =
+ 0x80_u32.wrapping_add(value >> 6 & 0x3F) as yaml_char_t;
+ let fresh578 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh578 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+ } else {
+ let fresh579 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh579 = 0xF0_u32.wrapping_add(value >> 18) as yaml_char_t;
+ let fresh580 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh580 =
+ 0x80_u32.wrapping_add(value >> 12 & 0x3F) as yaml_char_t;
+ let fresh581 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh581 =
+ 0x80_u32.wrapping_add(value >> 6 & 0x3F) as yaml_char_t;
+ let fresh582 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh582 = 0x80_u32.wrapping_add(value & 0x3F) as yaml_char_t;
+ }
+ k = 0_u64;
+ while k < code_length {
+ SKIP(parser);
+ k = k.wrapping_add(1);
+ }
+ }
+ }
+ } else {
+ READ!(parser, string);
+ }
+ }
+ if CACHE(parser, 2_u64).fail {
+ current_block = 8114179180390253173;
+ break 's_58;
+ }
+ }
+ if CACHE(parser, 1_u64).fail {
+ current_block = 8114179180390253173;
+ break;
+ }
+ if CHECK!((*parser).buffer, if single { b'\'' } else { b'"' }) {
+ current_block = 7468767852762055642;
+ break;
+ }
+ if CACHE(parser, 1_u64).fail {
+ current_block = 8114179180390253173;
+ break;
+ }
+ while IS_BLANK!((*parser).buffer) || IS_BREAK!((*parser).buffer) {
+ if IS_BLANK!((*parser).buffer) {
+ if !leading_blanks {
+ READ!(parser, whitespaces);
+ } else {
+ SKIP(parser);
+ }
+ } else {
+ if CACHE(parser, 2_u64).fail {
+ current_block = 8114179180390253173;
+ break 's_58;
+ }
+ if !leading_blanks {
+ CLEAR!(whitespaces);
+ READ_LINE!(parser, leading_break);
+ leading_blanks = true;
+ } else {
+ READ_LINE!(parser, trailing_breaks);
+ }
+ }
+ if CACHE(parser, 1_u64).fail {
+ current_block = 8114179180390253173;
+ break 's_58;
+ }
+ }
+ if leading_blanks {
+ if *leading_break.start == b'\n' {
+ if *trailing_breaks.start == b'\0' {
+ STRING_EXTEND!(string);
+ let fresh711 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh711 = b' ';
+ } else {
+ JOIN!(string, trailing_breaks);
+ CLEAR!(trailing_breaks);
+ }
+ CLEAR!(leading_break);
+ } else {
+ JOIN!(string, leading_break);
+ JOIN!(string, trailing_breaks);
+ CLEAR!(leading_break);
+ CLEAR!(trailing_breaks);
+ }
+ } else {
+ JOIN!(string, whitespaces);
+ CLEAR!(whitespaces);
+ }
+ }
+ }
+ if current_block != 8114179180390253173 {
+ SKIP(parser);
+ end_mark = (*parser).mark;
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_SCALAR_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ let fresh716 = addr_of_mut!((*token).data.scalar.value);
+ *fresh716 = string.start;
+ (*token).data.scalar.length =
+ string.pointer.c_offset_from(string.start) as libc::c_long as size_t;
+ (*token).data.scalar.style = if single {
+ YAML_SINGLE_QUOTED_SCALAR_STYLE
+ } else {
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE
+ };
+ STRING_DEL!(leading_break);
+ STRING_DEL!(trailing_breaks);
+ STRING_DEL!(whitespaces);
+ return OK;
+ }
+ STRING_DEL!(string);
+ STRING_DEL!(leading_break);
+ STRING_DEL!(trailing_breaks);
+ STRING_DEL!(whitespaces);
+ FAIL
+}
+
+unsafe fn yaml_parser_scan_plain_scalar(
+ parser: *mut yaml_parser_t,
+ token: *mut yaml_token_t,
+) -> Success {
+ let current_block: u64;
+ let mut end_mark: yaml_mark_t;
+ let mut string = NULL_STRING;
+ let mut leading_break = NULL_STRING;
+ let mut trailing_breaks = NULL_STRING;
+ let mut whitespaces = NULL_STRING;
+ let mut leading_blanks = false;
+ let indent: libc::c_int = (*parser).indent + 1;
+ STRING_INIT!(string);
+ STRING_INIT!(leading_break);
+ STRING_INIT!(trailing_breaks);
+ STRING_INIT!(whitespaces);
+ end_mark = (*parser).mark;
+ let start_mark: yaml_mark_t = end_mark;
+ 's_57: loop {
+ if CACHE(parser, 4_u64).fail {
+ current_block = 16642808987012640029;
+ break;
+ }
+ if (*parser).mark.column == 0_u64
+ && (CHECK_AT!((*parser).buffer, b'-', 0)
+ && CHECK_AT!((*parser).buffer, b'-', 1)
+ && CHECK_AT!((*parser).buffer, b'-', 2)
+ || CHECK_AT!((*parser).buffer, b'.', 0)
+ && CHECK_AT!((*parser).buffer, b'.', 1)
+ && CHECK_AT!((*parser).buffer, b'.', 2))
+ && IS_BLANKZ_AT!((*parser).buffer, 3)
+ {
+ current_block = 6281126495347172768;
+ break;
+ }
+ if CHECK!((*parser).buffer, b'#') {
+ current_block = 6281126495347172768;
+ break;
+ }
+ while !IS_BLANKZ!((*parser).buffer) {
+ if (*parser).flow_level != 0
+ && CHECK!((*parser).buffer, b':')
+ && (CHECK_AT!((*parser).buffer, b',', 1)
+ || CHECK_AT!((*parser).buffer, b'?', 1)
+ || CHECK_AT!((*parser).buffer, b'[', 1)
+ || CHECK_AT!((*parser).buffer, b']', 1)
+ || CHECK_AT!((*parser).buffer, b'{', 1)
+ || CHECK_AT!((*parser).buffer, b'}', 1))
+ {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a plain scalar\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found unexpected ':'\0" as *const u8 as *const libc::c_char,
+ );
+ current_block = 16642808987012640029;
+ break 's_57;
+ } else {
+ if CHECK!((*parser).buffer, b':') && IS_BLANKZ_AT!((*parser).buffer, 1)
+ || (*parser).flow_level != 0
+ && (CHECK!((*parser).buffer, b',')
+ || CHECK!((*parser).buffer, b'[')
+ || CHECK!((*parser).buffer, b']')
+ || CHECK!((*parser).buffer, b'{')
+ || CHECK!((*parser).buffer, b'}'))
+ {
+ break;
+ }
+ if leading_blanks || whitespaces.start != whitespaces.pointer {
+ if leading_blanks {
+ if *leading_break.start == b'\n' {
+ if *trailing_breaks.start == b'\0' {
+ STRING_EXTEND!(string);
+ let fresh717 = string.pointer;
+ string.pointer = string.pointer.wrapping_offset(1);
+ *fresh717 = b' ';
+ } else {
+ JOIN!(string, trailing_breaks);
+ CLEAR!(trailing_breaks);
+ }
+ CLEAR!(leading_break);
+ } else {
+ JOIN!(string, leading_break);
+ JOIN!(string, trailing_breaks);
+ CLEAR!(leading_break);
+ CLEAR!(trailing_breaks);
+ }
+ leading_blanks = false;
+ } else {
+ JOIN!(string, whitespaces);
+ CLEAR!(whitespaces);
+ }
+ }
+ READ!(parser, string);
+ end_mark = (*parser).mark;
+ if CACHE(parser, 2_u64).fail {
+ current_block = 16642808987012640029;
+ break 's_57;
+ }
+ }
+ }
+ if !(IS_BLANK!((*parser).buffer) || IS_BREAK!((*parser).buffer)) {
+ current_block = 6281126495347172768;
+ break;
+ }
+ if CACHE(parser, 1_u64).fail {
+ current_block = 16642808987012640029;
+ break;
+ }
+ while IS_BLANK!((*parser).buffer) || IS_BREAK!((*parser).buffer) {
+ if IS_BLANK!((*parser).buffer) {
+ if leading_blanks
+ && ((*parser).mark.column as libc::c_int) < indent
+ && IS_TAB!((*parser).buffer)
+ {
+ yaml_parser_set_scanner_error(
+ parser,
+ b"while scanning a plain scalar\0" as *const u8 as *const libc::c_char,
+ start_mark,
+ b"found a tab character that violates indentation\0" as *const u8
+ as *const libc::c_char,
+ );
+ current_block = 16642808987012640029;
+ break 's_57;
+ } else if !leading_blanks {
+ READ!(parser, whitespaces);
+ } else {
+ SKIP(parser);
+ }
+ } else {
+ if CACHE(parser, 2_u64).fail {
+ current_block = 16642808987012640029;
+ break 's_57;
+ }
+ if !leading_blanks {
+ CLEAR!(whitespaces);
+ READ_LINE!(parser, leading_break);
+ leading_blanks = true;
+ } else {
+ READ_LINE!(parser, trailing_breaks);
+ }
+ }
+ if CACHE(parser, 1_u64).fail {
+ current_block = 16642808987012640029;
+ break 's_57;
+ }
+ }
+ if (*parser).flow_level == 0 && ((*parser).mark.column as libc::c_int) < indent {
+ current_block = 6281126495347172768;
+ break;
+ }
+ }
+ if current_block != 16642808987012640029 {
+ memset(
+ token as *mut libc::c_void,
+ 0,
+ size_of::<yaml_token_t>() as libc::c_ulong,
+ );
+ (*token).type_ = YAML_SCALAR_TOKEN;
+ (*token).start_mark = start_mark;
+ (*token).end_mark = end_mark;
+ let fresh842 = addr_of_mut!((*token).data.scalar.value);
+ *fresh842 = string.start;
+ (*token).data.scalar.length =
+ string.pointer.c_offset_from(string.start) as libc::c_long as size_t;
+ (*token).data.scalar.style = YAML_PLAIN_SCALAR_STYLE;
+ if leading_blanks {
+ (*parser).simple_key_allowed = true;
+ }
+ STRING_DEL!(leading_break);
+ STRING_DEL!(trailing_breaks);
+ STRING_DEL!(whitespaces);
+ return OK;
+ }
+ STRING_DEL!(string);
+ STRING_DEL!(leading_break);
+ STRING_DEL!(trailing_breaks);
+ STRING_DEL!(whitespaces);
+ FAIL
+}
diff --git a/src/success.rs b/src/success.rs
new file mode 100644
index 0000000..c004d17
--- /dev/null
+++ b/src/success.rs
@@ -0,0 +1,25 @@
+use core::ops::Deref;
+
+pub const OK: Success = Success { ok: true };
+pub const FAIL: Success = Success { ok: false };
+
+#[must_use]
+pub struct Success {
+ pub ok: bool,
+}
+
+pub struct Failure {
+ pub fail: bool,
+}
+
+impl Deref for Success {
+ type Target = Failure;
+
+ fn deref(&self) -> &Self::Target {
+ if self.ok {
+ &Failure { fail: false }
+ } else {
+ &Failure { fail: true }
+ }
+ }
+}
diff --git a/src/writer.rs b/src/writer.rs
new file mode 100644
index 0000000..11405bc
--- /dev/null
+++ b/src/writer.rs
@@ -0,0 +1,148 @@
+use crate::success::{Success, FAIL, OK};
+use crate::yaml::size_t;
+use crate::{
+ libc, yaml_emitter_t, PointerExt, YAML_ANY_ENCODING, YAML_UTF16LE_ENCODING, YAML_UTF8_ENCODING,
+ YAML_WRITER_ERROR,
+};
+use core::ptr::addr_of_mut;
+
+unsafe fn yaml_emitter_set_writer_error(
+ emitter: *mut yaml_emitter_t,
+ problem: *const libc::c_char,
+) -> Success {
+ (*emitter).error = YAML_WRITER_ERROR;
+ let fresh0 = addr_of_mut!((*emitter).problem);
+ *fresh0 = problem;
+ FAIL
+}
+
+/// Flush the accumulated characters to the output.
+pub unsafe fn yaml_emitter_flush(emitter: *mut yaml_emitter_t) -> Success {
+ __assert!(!emitter.is_null());
+ __assert!(((*emitter).write_handler).is_some());
+ __assert!((*emitter).encoding != YAML_ANY_ENCODING);
+ let fresh1 = addr_of_mut!((*emitter).buffer.last);
+ *fresh1 = (*emitter).buffer.pointer;
+ let fresh2 = addr_of_mut!((*emitter).buffer.pointer);
+ *fresh2 = (*emitter).buffer.start;
+ if (*emitter).buffer.start == (*emitter).buffer.last {
+ return OK;
+ }
+ if (*emitter).encoding == YAML_UTF8_ENCODING {
+ if (*emitter).write_handler.expect("non-null function pointer")(
+ (*emitter).write_handler_data,
+ (*emitter).buffer.start,
+ (*emitter)
+ .buffer
+ .last
+ .c_offset_from((*emitter).buffer.start) as libc::c_long as size_t,
+ ) != 0
+ {
+ let fresh3 = addr_of_mut!((*emitter).buffer.last);
+ *fresh3 = (*emitter).buffer.start;
+ let fresh4 = addr_of_mut!((*emitter).buffer.pointer);
+ *fresh4 = (*emitter).buffer.start;
+ return OK;
+ } else {
+ return yaml_emitter_set_writer_error(
+ emitter,
+ b"write error\0" as *const u8 as *const libc::c_char,
+ );
+ }
+ }
+ let low: libc::c_int = if (*emitter).encoding == YAML_UTF16LE_ENCODING {
+ 0
+ } else {
+ 1
+ };
+ let high: libc::c_int = if (*emitter).encoding == YAML_UTF16LE_ENCODING {
+ 1
+ } else {
+ 0
+ };
+ while (*emitter).buffer.pointer != (*emitter).buffer.last {
+ let mut octet: libc::c_uchar;
+ let mut value: libc::c_uint;
+ let mut k: size_t;
+ octet = *(*emitter).buffer.pointer;
+ let width: libc::c_uint = if octet & 0x80 == 0 {
+ 1
+ } else if octet & 0xE0 == 0xC0 {
+ 2
+ } else if octet & 0xF0 == 0xE0 {
+ 3
+ } else if octet & 0xF8 == 0xF0 {
+ 4
+ } else {
+ 0
+ } as libc::c_uint;
+ value = if octet & 0x80 == 0 {
+ octet & 0x7F
+ } else if octet & 0xE0 == 0xC0 {
+ octet & 0x1F
+ } else if octet & 0xF0 == 0xE0 {
+ octet & 0xF
+ } else if octet & 0xF8 == 0xF0 {
+ octet & 0x7
+ } else {
+ 0
+ } as libc::c_uint;
+ k = 1_u64;
+ while k < width as libc::c_ulong {
+ octet = *(*emitter).buffer.pointer.wrapping_offset(k as isize);
+ value = (value << 6).wrapping_add((octet & 0x3F) as libc::c_uint);
+ k = k.wrapping_add(1);
+ }
+ let fresh5 = addr_of_mut!((*emitter).buffer.pointer);
+ *fresh5 = (*fresh5).wrapping_offset(width as isize);
+ if value < 0x10000 {
+ *(*emitter).raw_buffer.last.wrapping_offset(high as isize) =
+ (value >> 8) as libc::c_uchar;
+ *(*emitter).raw_buffer.last.wrapping_offset(low as isize) =
+ (value & 0xFF) as libc::c_uchar;
+ let fresh6 = addr_of_mut!((*emitter).raw_buffer.last);
+ *fresh6 = (*fresh6).wrapping_offset(2_isize);
+ } else {
+ value = value.wrapping_sub(0x10000);
+ *(*emitter).raw_buffer.last.wrapping_offset(high as isize) =
+ 0xD8_u32.wrapping_add(value >> 18) as libc::c_uchar;
+ *(*emitter).raw_buffer.last.wrapping_offset(low as isize) =
+ (value >> 10 & 0xFF) as libc::c_uchar;
+ *(*emitter)
+ .raw_buffer
+ .last
+ .wrapping_offset((high + 2) as isize) =
+ 0xDC_u32.wrapping_add(value >> 8 & 0xFF) as libc::c_uchar;
+ *(*emitter)
+ .raw_buffer
+ .last
+ .wrapping_offset((low + 2) as isize) = (value & 0xFF) as libc::c_uchar;
+ let fresh7 = addr_of_mut!((*emitter).raw_buffer.last);
+ *fresh7 = (*fresh7).wrapping_offset(4_isize);
+ }
+ }
+ if (*emitter).write_handler.expect("non-null function pointer")(
+ (*emitter).write_handler_data,
+ (*emitter).raw_buffer.start,
+ (*emitter)
+ .raw_buffer
+ .last
+ .c_offset_from((*emitter).raw_buffer.start) as libc::c_long as size_t,
+ ) != 0
+ {
+ let fresh8 = addr_of_mut!((*emitter).buffer.last);
+ *fresh8 = (*emitter).buffer.start;
+ let fresh9 = addr_of_mut!((*emitter).buffer.pointer);
+ *fresh9 = (*emitter).buffer.start;
+ let fresh10 = addr_of_mut!((*emitter).raw_buffer.last);
+ *fresh10 = (*emitter).raw_buffer.start;
+ let fresh11 = addr_of_mut!((*emitter).raw_buffer.pointer);
+ *fresh11 = (*emitter).raw_buffer.start;
+ OK
+ } else {
+ yaml_emitter_set_writer_error(
+ emitter,
+ b"write error\0" as *const u8 as *const libc::c_char,
+ )
+ }
+}
diff --git a/src/yaml.rs b/src/yaml.rs
new file mode 100644
index 0000000..dfffe9c
--- /dev/null
+++ b/src/yaml.rs
@@ -0,0 +1,1284 @@
+use crate::libc;
+use core::ops::Deref;
+use core::ptr::{self, addr_of};
+
+pub use self::{
+ yaml_break_t::*, yaml_emitter_state_t::*, yaml_encoding_t::*, yaml_error_type_t::*,
+ yaml_event_type_t::*, yaml_mapping_style_t::*, yaml_node_type_t::*, yaml_parser_state_t::*,
+ yaml_scalar_style_t::*, yaml_sequence_style_t::*, yaml_token_type_t::*,
+};
+pub use core::primitive::{i64 as ptrdiff_t, u64 as size_t, u8 as yaml_char_t};
+
+/// The version directive data.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_version_directive_t {
+ /// The major version number.
+ pub major: libc::c_int,
+ /// The minor version number.
+ pub minor: libc::c_int,
+}
+
+/// The tag directive data.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_tag_directive_t {
+ /// The tag handle.
+ pub handle: *mut yaml_char_t,
+ /// The tag prefix.
+ pub prefix: *mut yaml_char_t,
+}
+
+/// The stream encoding.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_encoding_t {
+ /// Let the parser choose the encoding.
+ YAML_ANY_ENCODING = 0,
+ /// The default UTF-8 encoding.
+ YAML_UTF8_ENCODING = 1,
+ /// The UTF-16-LE encoding with BOM.
+ YAML_UTF16LE_ENCODING = 2,
+ /// The UTF-16-BE encoding with BOM.
+ YAML_UTF16BE_ENCODING = 3,
+}
+
+/// Line break type.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_break_t {
+ /// Let the parser choose the break type.
+ YAML_ANY_BREAK = 0,
+ /// Use CR for line breaks (Mac style).
+ YAML_CR_BREAK = 1,
+ /// Use LN for line breaks (Unix style).
+ YAML_LN_BREAK = 2,
+ /// Use CR LN for line breaks (DOS style).
+ YAML_CRLN_BREAK = 3,
+}
+
+/// Many bad things could happen with the parser and emitter.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_error_type_t {
+ /// No error is produced.
+ YAML_NO_ERROR = 0,
+ /// Cannot allocate or reallocate a block of memory.
+ YAML_MEMORY_ERROR = 1,
+ /// Cannot read or decode the input stream.
+ YAML_READER_ERROR = 2,
+ /// Cannot scan the input stream.
+ YAML_SCANNER_ERROR = 3,
+ /// Cannot parse the input stream.
+ YAML_PARSER_ERROR = 4,
+ /// Cannot compose a YAML document.
+ YAML_COMPOSER_ERROR = 5,
+ /// Cannot write to the output stream.
+ YAML_WRITER_ERROR = 6,
+ /// Cannot emit a YAML stream.
+ YAML_EMITTER_ERROR = 7,
+}
+
+/// The pointer position.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_mark_t {
+ /// The position index.
+ pub index: size_t,
+ /// The position line.
+ pub line: size_t,
+ /// The position column.
+ pub column: size_t,
+}
+
+/// Scalar styles.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_scalar_style_t {
+ /// Let the emitter choose the style.
+ YAML_ANY_SCALAR_STYLE = 0,
+ /// The plain scalar style.
+ YAML_PLAIN_SCALAR_STYLE = 1,
+ /// The single-quoted scalar style.
+ YAML_SINGLE_QUOTED_SCALAR_STYLE = 2,
+ /// The double-quoted scalar style.
+ YAML_DOUBLE_QUOTED_SCALAR_STYLE = 3,
+ /// The literal scalar style.
+ YAML_LITERAL_SCALAR_STYLE = 4,
+ /// The folded scalar style.
+ YAML_FOLDED_SCALAR_STYLE = 5,
+}
+
+/// Sequence styles.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_sequence_style_t {
+ /// Let the emitter choose the style.
+ YAML_ANY_SEQUENCE_STYLE = 0,
+ /// The block sequence style.
+ YAML_BLOCK_SEQUENCE_STYLE = 1,
+ /// The flow sequence style.
+ YAML_FLOW_SEQUENCE_STYLE = 2,
+}
+
+/// Mapping styles.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_mapping_style_t {
+ /// Let the emitter choose the style.
+ YAML_ANY_MAPPING_STYLE = 0,
+ /// The block mapping style.
+ YAML_BLOCK_MAPPING_STYLE = 1,
+ /// The flow mapping style.
+ YAML_FLOW_MAPPING_STYLE = 2,
+}
+
+/// Token types.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_token_type_t {
+ /// An empty token.
+ YAML_NO_TOKEN = 0,
+ /// A STREAM-START token.
+ YAML_STREAM_START_TOKEN = 1,
+ /// A STREAM-END token.
+ YAML_STREAM_END_TOKEN = 2,
+ /// A VERSION-DIRECTIVE token.
+ YAML_VERSION_DIRECTIVE_TOKEN = 3,
+ /// A TAG-DIRECTIVE token.
+ YAML_TAG_DIRECTIVE_TOKEN = 4,
+ /// A DOCUMENT-START token.
+ YAML_DOCUMENT_START_TOKEN = 5,
+ /// A DOCUMENT-END token.
+ YAML_DOCUMENT_END_TOKEN = 6,
+ /// A BLOCK-SEQUENCE-START token.
+ YAML_BLOCK_SEQUENCE_START_TOKEN = 7,
+ /// A BLOCK-MAPPING-START token.
+ YAML_BLOCK_MAPPING_START_TOKEN = 8,
+ /// A BLOCK-END token.
+ YAML_BLOCK_END_TOKEN = 9,
+ /// A FLOW-SEQUENCE-START token.
+ YAML_FLOW_SEQUENCE_START_TOKEN = 10,
+ /// A FLOW-SEQUENCE-END token.
+ YAML_FLOW_SEQUENCE_END_TOKEN = 11,
+ /// A FLOW-MAPPING-START token.
+ YAML_FLOW_MAPPING_START_TOKEN = 12,
+ /// A FLOW-MAPPING-END token.
+ YAML_FLOW_MAPPING_END_TOKEN = 13,
+ /// A BLOCK-ENTRY token.
+ YAML_BLOCK_ENTRY_TOKEN = 14,
+ /// A FLOW-ENTRY token.
+ YAML_FLOW_ENTRY_TOKEN = 15,
+ /// A KEY token.
+ YAML_KEY_TOKEN = 16,
+ /// A VALUE token.
+ YAML_VALUE_TOKEN = 17,
+ /// An ALIAS token.
+ YAML_ALIAS_TOKEN = 18,
+ /// An ANCHOR token.
+ YAML_ANCHOR_TOKEN = 19,
+ /// A TAG token.
+ YAML_TAG_TOKEN = 20,
+ /// A SCALAR token.
+ YAML_SCALAR_TOKEN = 21,
+}
+
+/// The token structure.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_token_t {
+ /// The token type.
+ pub type_: yaml_token_type_t,
+ /// The token data.
+ ///
+ /// ```
+ /// # const _: &str = stringify! {
+ /// union {
+ /// /// The stream start (for YAML_STREAM_START_TOKEN).
+ /// stream_start: struct {
+ /// /// The stream encoding.
+ /// encoding: yaml_encoding_t,
+ /// },
+ /// /// The alias (for YAML_ALIAS_TOKEN).
+ /// alias: struct {
+ /// /// The alias value.
+ /// value: *mut u8,
+ /// },
+ /// /// The anchor (for YAML_ANCHOR_TOKEN).
+ /// anchor: struct {
+ /// /// The anchor value.
+ /// value: *mut u8,
+ /// },
+ /// /// The tag (for YAML_TAG_TOKEN).
+ /// tag: struct {
+ /// /// The tag handle.
+ /// handle: *mut u8,
+ /// /// The tag suffix.
+ /// suffix: *mut u8,
+ /// },
+ /// /// The scalar value (for YAML_SCALAR_TOKEN).
+ /// scalar: struct {
+ /// /// The scalar value.
+ /// value: *mut u8,
+ /// /// The length of the scalar value.
+ /// length: u64,
+ /// /// The scalar style.
+ /// style: yaml_scalar_style_t,
+ /// },
+ /// /// The version directive (for YAML_VERSION_DIRECTIVE_TOKEN).
+ /// version_directive: struct {
+ /// /// The major version number.
+ /// major: i32,
+ /// /// The minor version number.
+ /// minor: i32,
+ /// },
+ /// /// The tag directive (for YAML_TAG_DIRECTIVE_TOKEN).
+ /// tag_directive: struct {
+ /// /// The tag handle.
+ /// handle: *mut u8,
+ /// /// The tag prefix.
+ /// prefix: *mut u8,
+ /// },
+ /// }
+ /// # };
+ /// ```
+ pub data: unnamed_yaml_token_t_data,
+ /// The beginning of the token.
+ pub start_mark: yaml_mark_t,
+ /// The end of the token.
+ pub end_mark: yaml_mark_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub union unnamed_yaml_token_t_data {
+ /// The stream start (for YAML_STREAM_START_TOKEN).
+ pub stream_start: unnamed_yaml_token_t_data_stream_start,
+ /// The alias (for YAML_ALIAS_TOKEN).
+ pub alias: unnamed_yaml_token_t_data_alias,
+ /// The anchor (for YAML_ANCHOR_TOKEN).
+ pub anchor: unnamed_yaml_token_t_data_anchor,
+ /// The tag (for YAML_TAG_TOKEN).
+ pub tag: unnamed_yaml_token_t_data_tag,
+ /// The scalar value (for YAML_SCALAR_TOKEN).
+ pub scalar: unnamed_yaml_token_t_data_scalar,
+ /// The version directive (for YAML_VERSION_DIRECTIVE_TOKEN).
+ pub version_directive: unnamed_yaml_token_t_data_version_directive,
+ /// The tag directive (for YAML_TAG_DIRECTIVE_TOKEN).
+ pub tag_directive: unnamed_yaml_token_t_data_tag_directive,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_token_t_data_stream_start {
+ /// The stream encoding.
+ pub encoding: yaml_encoding_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_token_t_data_alias {
+ /// The alias value.
+ pub value: *mut yaml_char_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_token_t_data_anchor {
+ /// The anchor value.
+ pub value: *mut yaml_char_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_token_t_data_tag {
+ /// The tag handle.
+ pub handle: *mut yaml_char_t,
+ /// The tag suffix.
+ pub suffix: *mut yaml_char_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_token_t_data_scalar {
+ /// The scalar value.
+ pub value: *mut yaml_char_t,
+ /// The length of the scalar value.
+ pub length: size_t,
+ /// The scalar style.
+ pub style: yaml_scalar_style_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_token_t_data_version_directive {
+ /// The major version number.
+ pub major: libc::c_int,
+ /// The minor version number.
+ pub minor: libc::c_int,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_token_t_data_tag_directive {
+ /// The tag handle.
+ pub handle: *mut yaml_char_t,
+ /// The tag prefix.
+ pub prefix: *mut yaml_char_t,
+}
+
+/// Event types.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_event_type_t {
+ /// An empty event.
+ YAML_NO_EVENT = 0,
+ /// A STREAM-START event.
+ YAML_STREAM_START_EVENT = 1,
+ /// A STREAM-END event.
+ YAML_STREAM_END_EVENT = 2,
+ /// A DOCUMENT-START event.
+ YAML_DOCUMENT_START_EVENT = 3,
+ /// A DOCUMENT-END event.
+ YAML_DOCUMENT_END_EVENT = 4,
+ /// An ALIAS event.
+ YAML_ALIAS_EVENT = 5,
+ /// A SCALAR event.
+ YAML_SCALAR_EVENT = 6,
+ /// A SEQUENCE-START event.
+ YAML_SEQUENCE_START_EVENT = 7,
+ /// A SEQUENCE-END event.
+ YAML_SEQUENCE_END_EVENT = 8,
+ /// A MAPPING-START event.
+ YAML_MAPPING_START_EVENT = 9,
+ /// A MAPPING-END event.
+ YAML_MAPPING_END_EVENT = 10,
+}
+
+/// The event structure.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_event_t {
+ /// The event type.
+ pub type_: yaml_event_type_t,
+ /// The event data.
+ ///
+ /// ```
+ /// # const _: &str = stringify! {
+ /// union {
+ /// /// The stream parameters (for YAML_STREAM_START_EVENT).
+ /// stream_start: struct {
+ /// /// The document encoding.
+ /// encoding: yaml_encoding_t,
+ /// },
+ /// /// The document parameters (for YAML_DOCUMENT_START_EVENT).
+ /// document_start: struct {
+ /// /// The version directive.
+ /// version_directive: *mut yaml_version_directive_t,
+ /// /// The list of tag directives.
+ /// tag_directives: struct {
+ /// /// The beginning of the tag directives list.
+ /// start: *mut yaml_tag_directive_t,
+ /// /// The end of the tag directives list.
+ /// end: *mut yaml_tag_directive_t,
+ /// },
+ /// /// Is the document indicator implicit?
+ /// implicit: i32,
+ /// },
+ /// /// The document end parameters (for YAML_DOCUMENT_END_EVENT).
+ /// document_end: struct {
+ /// /// Is the document end indicator implicit?
+ /// implicit: i32,
+ /// },
+ /// /// The alias parameters (for YAML_ALIAS_EVENT).
+ /// alias: struct {
+ /// /// The anchor.
+ /// anchor: *mut u8,
+ /// },
+ /// /// The scalar parameters (for YAML_SCALAR_EVENT).
+ /// scalar: struct {
+ /// /// The anchor.
+ /// anchor: *mut u8,
+ /// /// The tag.
+ /// tag: *mut u8,
+ /// /// The scalar value.
+ /// value: *mut u8,
+ /// /// The length of the scalar value.
+ /// length: u64,
+ /// /// Is the tag optional for the plain style?
+ /// plain_implicit: i32,
+ /// /// Is the tag optional for any non-plain style?
+ /// quoted_implicit: i32,
+ /// /// The scalar style.
+ /// style: yaml_scalar_style_t,
+ /// },
+ /// /// The sequence parameters (for YAML_SEQUENCE_START_EVENT).
+ /// sequence_start: struct {
+ /// /// The anchor.
+ /// anchor: *mut u8,
+ /// /// The tag.
+ /// tag: *mut u8,
+ /// /// Is the tag optional?
+ /// implicit: i32,
+ /// /// The sequence style.
+ /// style: yaml_sequence_style_t,
+ /// },
+ /// /// The mapping parameters (for YAML_MAPPING_START_EVENT).
+ /// mapping_start: struct {
+ /// /// The anchor.
+ /// anchor: *mut u8,
+ /// /// The tag.
+ /// tag: *mut u8,
+ /// /// Is the tag optional?
+ /// implicit: i32,
+ /// /// The mapping style.
+ /// style: yaml_mapping_style_t,
+ /// },
+ /// }
+ /// # };
+ /// ```
+ pub data: unnamed_yaml_event_t_data,
+ /// The beginning of the event.
+ pub start_mark: yaml_mark_t,
+ /// The end of the event.
+ pub end_mark: yaml_mark_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub union unnamed_yaml_event_t_data {
+ /// The stream parameters (for YAML_STREAM_START_EVENT).
+ pub stream_start: unnamed_yaml_event_t_data_stream_start,
+ /// The document parameters (for YAML_DOCUMENT_START_EVENT).
+ pub document_start: unnamed_yaml_event_t_data_document_start,
+ /// The document end parameters (for YAML_DOCUMENT_END_EVENT).
+ pub document_end: unnamed_yaml_event_t_data_document_end,
+ /// The alias parameters (for YAML_ALIAS_EVENT).
+ pub alias: unnamed_yaml_event_t_data_alias,
+ /// The scalar parameters (for YAML_SCALAR_EVENT).
+ pub scalar: unnamed_yaml_event_t_data_scalar,
+ /// The sequence parameters (for YAML_SEQUENCE_START_EVENT).
+ pub sequence_start: unnamed_yaml_event_t_data_sequence_start,
+ /// The mapping parameters (for YAML_MAPPING_START_EVENT).
+ pub mapping_start: unnamed_yaml_event_t_data_mapping_start,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_event_t_data_stream_start {
+ /// The document encoding.
+ pub encoding: yaml_encoding_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_event_t_data_document_start {
+ /// The version directive.
+ pub version_directive: *mut yaml_version_directive_t,
+ /// The list of tag directives.
+ pub tag_directives: unnamed_yaml_event_t_data_document_start_tag_directives,
+ /// Is the document indicator implicit?
+ pub implicit: bool,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_event_t_data_document_start_tag_directives {
+ /// The beginning of the tag directives list.
+ pub start: *mut yaml_tag_directive_t,
+ /// The end of the tag directives list.
+ pub end: *mut yaml_tag_directive_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_event_t_data_document_end {
+ /// Is the document end indicator implicit?
+ pub implicit: bool,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_event_t_data_alias {
+ /// The anchor.
+ pub anchor: *mut yaml_char_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_event_t_data_scalar {
+ /// The anchor.
+ pub anchor: *mut yaml_char_t,
+ /// The tag.
+ pub tag: *mut yaml_char_t,
+ /// The scalar value.
+ pub value: *mut yaml_char_t,
+ /// The length of the scalar value.
+ pub length: size_t,
+ /// Is the tag optional for the plain style?
+ pub plain_implicit: bool,
+ /// Is the tag optional for any non-plain style?
+ pub quoted_implicit: bool,
+ /// The scalar style.
+ pub style: yaml_scalar_style_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_event_t_data_sequence_start {
+ /// The anchor.
+ pub anchor: *mut yaml_char_t,
+ /// The tag.
+ pub tag: *mut yaml_char_t,
+ /// Is the tag optional?
+ pub implicit: bool,
+ /// The sequence style.
+ pub style: yaml_sequence_style_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_event_t_data_mapping_start {
+ /// The anchor.
+ pub anchor: *mut yaml_char_t,
+ /// The tag.
+ pub tag: *mut yaml_char_t,
+ /// Is the tag optional?
+ pub implicit: bool,
+ /// The mapping style.
+ pub style: yaml_mapping_style_t,
+}
+
+/// Node types.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_node_type_t {
+ /// An empty node.
+ YAML_NO_NODE = 0,
+ /// A scalar node.
+ YAML_SCALAR_NODE = 1,
+ /// A sequence node.
+ YAML_SEQUENCE_NODE = 2,
+ /// A mapping node.
+ YAML_MAPPING_NODE = 3,
+}
+
+/// The node structure.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_node_t {
+ /// The node type.
+ pub type_: yaml_node_type_t,
+ /// The node tag.
+ pub tag: *mut yaml_char_t,
+ /// The node data.
+ ///
+ /// ```
+ /// # const _: &str = stringify! {
+ /// union {
+ /// /// The scalar parameters (for YAML_SCALAR_NODE).
+ /// scalar: struct {
+ /// /// The scalar value.
+ /// value: *mut u8,
+ /// /// The length of the scalar value.
+ /// length: u64,
+ /// /// The scalar style.
+ /// style: yaml_scalar_style_t,
+ /// },
+ /// /// The sequence parameters (for YAML_SEQUENCE_NODE).
+ /// sequence: struct {
+ /// /// The stack of sequence items.
+ /// items: yaml_stack_t<yaml_node_item_t>,
+ /// /// The sequence style.
+ /// style: yaml_sequence_style_t,
+ /// },
+ /// /// The mapping parameters (for YAML_MAPPING_NODE).
+ /// mapping: struct {
+ /// /// The stack of mapping pairs (key, value).
+ /// pairs: yaml_stack_t<yaml_node_pair_t>,
+ /// /// The mapping style.
+ /// style: yaml_mapping_style_t,
+ /// },
+ /// }
+ /// # };
+ /// ```
+ pub data: unnamed_yaml_node_t_data,
+ /// The beginning of the node.
+ pub start_mark: yaml_mark_t,
+ /// The end of the node.
+ pub end_mark: yaml_mark_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub union unnamed_yaml_node_t_data {
+ /// The scalar parameters (for YAML_SCALAR_NODE).
+ pub scalar: unnamed_yaml_node_t_data_scalar,
+ /// The sequence parameters (for YAML_SEQUENCE_NODE).
+ pub sequence: unnamed_yaml_node_t_data_sequence,
+ /// The mapping parameters (for YAML_MAPPING_NODE).
+ pub mapping: unnamed_yaml_node_t_data_mapping,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_node_t_data_scalar {
+ /// The scalar value.
+ pub value: *mut yaml_char_t,
+ /// The length of the scalar value.
+ pub length: size_t,
+ /// The scalar style.
+ pub style: yaml_scalar_style_t,
+}
+
+/// An element of a sequence node.
+pub type yaml_node_item_t = libc::c_int;
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_node_t_data_sequence {
+ /// The stack of sequence items.
+ pub items: yaml_stack_t<yaml_node_item_t>,
+ /// The sequence style.
+ pub style: yaml_sequence_style_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_node_t_data_mapping {
+ /// The stack of mapping pairs (key, value).
+ pub pairs: yaml_stack_t<yaml_node_pair_t>,
+ /// The mapping style.
+ pub style: yaml_mapping_style_t,
+}
+
+/// An element of a mapping node.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_node_pair_t {
+ /// The key of the element.
+ pub key: libc::c_int,
+ /// The value of the element.
+ pub value: libc::c_int,
+}
+
+/// The document structure.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_document_t {
+ /// The document nodes.
+ pub nodes: yaml_stack_t<yaml_node_t>,
+ /// The version directive.
+ pub version_directive: *mut yaml_version_directive_t,
+ /// The list of tag directives.
+ ///
+ /// ```
+ /// # const _: &str = stringify! {
+ /// struct {
+ /// /// The beginning of the tag directives list.
+ /// start: *mut yaml_tag_directive_t,
+ /// /// The end of the tag directives list.
+ /// end: *mut yaml_tag_directive_t,
+ /// }
+ /// # };
+ /// ```
+ pub tag_directives: unnamed_yaml_document_t_tag_directives,
+ /// Is the document start indicator implicit?
+ pub start_implicit: bool,
+ /// Is the document end indicator implicit?
+ pub end_implicit: bool,
+ /// The beginning of the document.
+ pub start_mark: yaml_mark_t,
+ /// The end of the document.
+ pub end_mark: yaml_mark_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct unnamed_yaml_document_t_tag_directives {
+ /// The beginning of the tag directives list.
+ pub start: *mut yaml_tag_directive_t,
+ /// The end of the tag directives list.
+ pub end: *mut yaml_tag_directive_t,
+}
+
+/// The prototype of a read handler.
+///
+/// The read handler is called when the parser needs to read more bytes from the
+/// source. The handler should write not more than `size` bytes to the `buffer`.
+/// The number of written bytes should be set to the `length` variable.
+///
+/// On success, the handler should return 1. If the handler failed, the returned
+/// value should be 0. On EOF, the handler should set the `size_read` to 0 and
+/// return 1.
+pub type yaml_read_handler_t = unsafe fn(
+ data: *mut libc::c_void,
+ buffer: *mut libc::c_uchar,
+ size: size_t,
+ size_read: *mut size_t,
+) -> libc::c_int;
+
+/// This structure holds information about a potential simple key.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_simple_key_t {
+ /// Is a simple key possible?
+ pub possible: bool,
+ /// Is a simple key required?
+ pub required: bool,
+ /// The number of the token.
+ pub token_number: size_t,
+ /// The position mark.
+ pub mark: yaml_mark_t,
+}
+
+/// The states of the parser.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_parser_state_t {
+ /// Expect STREAM-START.
+ YAML_PARSE_STREAM_START_STATE = 0,
+ /// Expect the beginning of an implicit document.
+ YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE = 1,
+ /// Expect DOCUMENT-START.
+ YAML_PARSE_DOCUMENT_START_STATE = 2,
+ /// Expect the content of a document.
+ YAML_PARSE_DOCUMENT_CONTENT_STATE = 3,
+ /// Expect DOCUMENT-END.
+ YAML_PARSE_DOCUMENT_END_STATE = 4,
+ /// Expect a block node.
+ YAML_PARSE_BLOCK_NODE_STATE = 5,
+ /// Expect a block node or indentless sequence.
+ YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE = 6,
+ /// Expect a flow node.
+ YAML_PARSE_FLOW_NODE_STATE = 7,
+ /// Expect the first entry of a block sequence.
+ YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE = 8,
+ /// Expect an entry of a block sequence.
+ YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE = 9,
+ /// Expect an entry of an indentless sequence.
+ YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE = 10,
+ /// Expect the first key of a block mapping.
+ YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE = 11,
+ /// Expect a block mapping key.
+ YAML_PARSE_BLOCK_MAPPING_KEY_STATE = 12,
+ /// Expect a block mapping value.
+ YAML_PARSE_BLOCK_MAPPING_VALUE_STATE = 13,
+ /// Expect the first entry of a flow sequence.
+ YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE = 14,
+ /// Expect an entry of a flow sequence.
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE = 15,
+ /// Expect a key of an ordered mapping.
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE = 16,
+ /// Expect a value of an ordered mapping.
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE = 17,
+ /// Expect the and of an ordered mapping entry.
+ YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE = 18,
+ /// Expect the first key of a flow mapping.
+ YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE = 19,
+ /// Expect a key of a flow mapping.
+ YAML_PARSE_FLOW_MAPPING_KEY_STATE = 20,
+ /// Expect a value of a flow mapping.
+ YAML_PARSE_FLOW_MAPPING_VALUE_STATE = 21,
+ /// Expect an empty value of a flow mapping.
+ YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE = 22,
+ /// Expect nothing.
+ YAML_PARSE_END_STATE = 23,
+}
+
+/// This structure holds aliases data.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_alias_data_t {
+ /// The anchor.
+ pub anchor: *mut yaml_char_t,
+ /// The node id.
+ pub index: libc::c_int,
+ /// The anchor mark.
+ pub mark: yaml_mark_t,
+}
+
+/// The parser structure.
+///
+/// All members are internal. Manage the structure using the `yaml_parser_`
+/// family of functions.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_parser_t {
+ /// Error type.
+ #[cfg(doc)]
+ pub error: yaml_error_type_t,
+ #[cfg(not(doc))]
+ pub(crate) error: yaml_error_type_t,
+ /// Error description.
+ #[cfg(doc)]
+ pub problem: *const libc::c_char,
+ #[cfg(not(doc))]
+ pub(crate) problem: *const libc::c_char,
+ /// The byte about which the problem occured.
+ #[cfg(doc)]
+ pub problem_offset: size_t,
+ #[cfg(not(doc))]
+ pub(crate) problem_offset: size_t,
+ /// The problematic value (-1 is none).
+ #[cfg(doc)]
+ pub problem_value: libc::c_int,
+ #[cfg(not(doc))]
+ pub(crate) problem_value: libc::c_int,
+ /// The problem position.
+ #[cfg(doc)]
+ pub problem_mark: yaml_mark_t,
+ #[cfg(not(doc))]
+ pub(crate) problem_mark: yaml_mark_t,
+ /// The error context.
+ #[cfg(doc)]
+ pub context: *const libc::c_char,
+ #[cfg(not(doc))]
+ pub(crate) context: *const libc::c_char,
+ /// The context position.
+ #[cfg(doc)]
+ pub context_mark: yaml_mark_t,
+ #[cfg(not(doc))]
+ pub(crate) context_mark: yaml_mark_t,
+ /// Read handler.
+ pub(crate) read_handler: Option<yaml_read_handler_t>,
+ /// A pointer for passing to the read handler.
+ pub(crate) read_handler_data: *mut libc::c_void,
+ /// Standard (string or file) input data.
+ pub(crate) input: unnamed_yaml_parser_t_input,
+ /// EOF flag
+ pub(crate) eof: bool,
+ /// The working buffer.
+ pub(crate) buffer: yaml_buffer_t<yaml_char_t>,
+ /// The number of unread characters in the buffer.
+ pub(crate) unread: size_t,
+ /// The raw buffer.
+ pub(crate) raw_buffer: yaml_buffer_t<libc::c_uchar>,
+ /// The input encoding.
+ pub(crate) encoding: yaml_encoding_t,
+ /// The offset of the current position (in bytes).
+ pub(crate) offset: size_t,
+ /// The mark of the current position.
+ pub(crate) mark: yaml_mark_t,
+ /// Have we started to scan the input stream?
+ pub(crate) stream_start_produced: bool,
+ /// Have we reached the end of the input stream?
+ pub(crate) stream_end_produced: bool,
+ /// The number of unclosed '[' and '{' indicators.
+ pub(crate) flow_level: libc::c_int,
+ /// The tokens queue.
+ pub(crate) tokens: yaml_queue_t<yaml_token_t>,
+ /// The number of tokens fetched from the queue.
+ pub(crate) tokens_parsed: size_t,
+ /// Does the tokens queue contain a token ready for dequeueing.
+ pub(crate) token_available: bool,
+ /// The indentation levels stack.
+ pub(crate) indents: yaml_stack_t<libc::c_int>,
+ /// The current indentation level.
+ pub(crate) indent: libc::c_int,
+ /// May a simple key occur at the current position?
+ pub(crate) simple_key_allowed: bool,
+ /// The stack of simple keys.
+ pub(crate) simple_keys: yaml_stack_t<yaml_simple_key_t>,
+ /// The parser states stack.
+ pub(crate) states: yaml_stack_t<yaml_parser_state_t>,
+ /// The current parser state.
+ pub(crate) state: yaml_parser_state_t,
+ /// The stack of marks.
+ pub(crate) marks: yaml_stack_t<yaml_mark_t>,
+ /// The list of TAG directives.
+ pub(crate) tag_directives: yaml_stack_t<yaml_tag_directive_t>,
+ /// The alias data.
+ pub(crate) aliases: yaml_stack_t<yaml_alias_data_t>,
+ /// The currently parsed document.
+ pub(crate) document: *mut yaml_document_t,
+}
+
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_parser_t_prefix {
+ /// Error type.
+ pub error: yaml_error_type_t,
+ /// Error description.
+ pub problem: *const libc::c_char,
+ /// The byte about which the problem occured.
+ pub problem_offset: size_t,
+ /// The problematic value (-1 is none).
+ pub problem_value: libc::c_int,
+ /// The problem position.
+ pub problem_mark: yaml_mark_t,
+ /// The error context.
+ pub context: *const libc::c_char,
+ /// The context position.
+ pub context_mark: yaml_mark_t,
+}
+
+#[doc(hidden)]
+impl Deref for yaml_parser_t {
+ type Target = yaml_parser_t_prefix;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*addr_of!(*self).cast() }
+ }
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub(crate) union unnamed_yaml_parser_t_input {
+ /// String input data.
+ pub string: unnamed_yaml_parser_t_input_string,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub(crate) struct unnamed_yaml_parser_t_input_string {
+ /// The string start pointer.
+ pub start: *const libc::c_uchar,
+ /// The string end pointer.
+ pub end: *const libc::c_uchar,
+ /// The string current position.
+ pub current: *const libc::c_uchar,
+}
+
+/// The prototype of a write handler.
+///
+/// The write handler is called when the emitter needs to flush the accumulated
+/// characters to the output. The handler should write `size` bytes of the
+/// `buffer` to the output.
+///
+/// On success, the handler should return 1. If the handler failed, the returned
+/// value should be 0.
+pub type yaml_write_handler_t =
+ unsafe fn(data: *mut libc::c_void, buffer: *mut libc::c_uchar, size: size_t) -> libc::c_int;
+
+/// The emitter states.
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[repr(u32)]
+#[non_exhaustive]
+pub enum yaml_emitter_state_t {
+ /// Expect STREAM-START.
+ YAML_EMIT_STREAM_START_STATE = 0,
+ /// Expect the first DOCUMENT-START or STREAM-END.
+ YAML_EMIT_FIRST_DOCUMENT_START_STATE = 1,
+ /// Expect DOCUMENT-START or STREAM-END.
+ YAML_EMIT_DOCUMENT_START_STATE = 2,
+ /// Expect the content of a document.
+ YAML_EMIT_DOCUMENT_CONTENT_STATE = 3,
+ /// Expect DOCUMENT-END.
+ YAML_EMIT_DOCUMENT_END_STATE = 4,
+ /// Expect the first item of a flow sequence.
+ YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE = 5,
+ /// Expect an item of a flow sequence.
+ YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE = 6,
+ /// Expect the first key of a flow mapping.
+ YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE = 7,
+ /// Expect a key of a flow mapping.
+ YAML_EMIT_FLOW_MAPPING_KEY_STATE = 8,
+ /// Expect a value for a simple key of a flow mapping.
+ YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE = 9,
+ /// Expect a value of a flow mapping.
+ YAML_EMIT_FLOW_MAPPING_VALUE_STATE = 10,
+ /// Expect the first item of a block sequence.
+ YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE = 11,
+ /// Expect an item of a block sequence.
+ YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE = 12,
+ /// Expect the first key of a block mapping.
+ YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE = 13,
+ /// Expect the key of a block mapping.
+ YAML_EMIT_BLOCK_MAPPING_KEY_STATE = 14,
+ /// Expect a value for a simple key of a block mapping.
+ YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE = 15,
+ /// Expect a value of a block mapping.
+ YAML_EMIT_BLOCK_MAPPING_VALUE_STATE = 16,
+ /// Expect nothing.
+ YAML_EMIT_END_STATE = 17,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub(crate) struct yaml_anchors_t {
+ /// The number of references.
+ pub references: libc::c_int,
+ /// The anchor id.
+ pub anchor: libc::c_int,
+ /// If the node has been emitted?
+ pub serialized: bool,
+}
+
+/// The emitter structure.
+///
+/// All members are internal. Manage the structure using the `yaml_emitter_`
+/// family of functions.
+#[derive(Copy, Clone)]
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_emitter_t {
+ /// Error type.
+ #[cfg(doc)]
+ pub error: yaml_error_type_t,
+ #[cfg(not(doc))]
+ pub(crate) error: yaml_error_type_t,
+ /// Error description.
+ #[cfg(doc)]
+ pub problem: *const libc::c_char,
+ #[cfg(not(doc))]
+ pub(crate) problem: *const libc::c_char,
+ /// Write handler.
+ pub(crate) write_handler: Option<yaml_write_handler_t>,
+ /// A pointer for passing to the write handler.
+ pub(crate) write_handler_data: *mut libc::c_void,
+ /// Standard (string or file) output data.
+ pub(crate) output: unnamed_yaml_emitter_t_output,
+ /// The working buffer.
+ pub(crate) buffer: yaml_buffer_t<yaml_char_t>,
+ /// The raw buffer.
+ pub(crate) raw_buffer: yaml_buffer_t<libc::c_uchar>,
+ /// The stream encoding.
+ pub(crate) encoding: yaml_encoding_t,
+ /// If the output is in the canonical style?
+ pub(crate) canonical: bool,
+ /// The number of indentation spaces.
+ pub(crate) best_indent: libc::c_int,
+ /// The preferred width of the output lines.
+ pub(crate) best_width: libc::c_int,
+ /// Allow unescaped non-ASCII characters?
+ pub(crate) unicode: bool,
+ /// The preferred line break.
+ pub(crate) line_break: yaml_break_t,
+ /// The stack of states.
+ pub(crate) states: yaml_stack_t<yaml_emitter_state_t>,
+ /// The current emitter state.
+ pub(crate) state: yaml_emitter_state_t,
+ /// The event queue.
+ pub(crate) events: yaml_queue_t<yaml_event_t>,
+ /// The stack of indentation levels.
+ pub(crate) indents: yaml_stack_t<libc::c_int>,
+ /// The list of tag directives.
+ pub(crate) tag_directives: yaml_stack_t<yaml_tag_directive_t>,
+ /// The current indentation level.
+ pub(crate) indent: libc::c_int,
+ /// The current flow level.
+ pub(crate) flow_level: libc::c_int,
+ /// Is it the document root context?
+ pub(crate) root_context: bool,
+ /// Is it a sequence context?
+ pub(crate) sequence_context: bool,
+ /// Is it a mapping context?
+ pub(crate) mapping_context: bool,
+ /// Is it a simple mapping key context?
+ pub(crate) simple_key_context: bool,
+ /// The current line.
+ pub(crate) line: libc::c_int,
+ /// The current column.
+ pub(crate) column: libc::c_int,
+ /// If the last character was a whitespace?
+ pub(crate) whitespace: bool,
+ /// If the last character was an indentation character (' ', '-', '?', ':')?
+ pub(crate) indention: bool,
+ /// If an explicit document end is required?
+ pub(crate) open_ended: libc::c_int,
+ /// Anchor analysis.
+ pub(crate) anchor_data: unnamed_yaml_emitter_t_anchor_data,
+ /// Tag analysis.
+ pub(crate) tag_data: unnamed_yaml_emitter_t_tag_data,
+ /// Scalar analysis.
+ pub(crate) scalar_data: unnamed_yaml_emitter_t_scalar_data,
+ /// If the stream was already opened?
+ pub(crate) opened: bool,
+ /// If the stream was already closed?
+ pub(crate) closed: bool,
+ /// The information associated with the document nodes.
+ pub(crate) anchors: *mut yaml_anchors_t,
+ /// The last assigned anchor id.
+ pub(crate) last_anchor_id: libc::c_int,
+ /// The currently emitted document.
+ pub(crate) document: *mut yaml_document_t,
+}
+
+#[repr(C)]
+#[non_exhaustive]
+pub struct yaml_emitter_t_prefix {
+ /// Error type.
+ pub error: yaml_error_type_t,
+ /// Error description.
+ pub problem: *const libc::c_char,
+}
+
+#[doc(hidden)]
+impl Deref for yaml_emitter_t {
+ type Target = yaml_emitter_t_prefix;
+ fn deref(&self) -> &Self::Target {
+ unsafe { &*addr_of!(*self).cast() }
+ }
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub(crate) union unnamed_yaml_emitter_t_output {
+ /// String output data.
+ pub string: unnamed_yaml_emitter_t_output_string,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub(crate) struct unnamed_yaml_emitter_t_output_string {
+ /// The buffer pointer.
+ pub buffer: *mut libc::c_uchar,
+ /// The buffer size.
+ pub size: size_t,
+ /// The number of written bytes.
+ pub size_written: *mut size_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub(crate) struct unnamed_yaml_emitter_t_anchor_data {
+ /// The anchor value.
+ pub anchor: *mut yaml_char_t,
+ /// The anchor length.
+ pub anchor_length: size_t,
+ /// Is it an alias?
+ pub alias: bool,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub(crate) struct unnamed_yaml_emitter_t_tag_data {
+ /// The tag handle.
+ pub handle: *mut yaml_char_t,
+ /// The tag handle length.
+ pub handle_length: size_t,
+ /// The tag suffix.
+ pub suffix: *mut yaml_char_t,
+ /// The tag suffix length.
+ pub suffix_length: size_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub(crate) struct unnamed_yaml_emitter_t_scalar_data {
+ /// The scalar value.
+ pub value: *mut yaml_char_t,
+ /// The scalar length.
+ pub length: size_t,
+ /// Does the scalar contain line breaks?
+ pub multiline: bool,
+ /// Can the scalar be expessed in the flow plain style?
+ pub flow_plain_allowed: bool,
+ /// Can the scalar be expressed in the block plain style?
+ pub block_plain_allowed: bool,
+ /// Can the scalar be expressed in the single quoted style?
+ pub single_quoted_allowed: bool,
+ /// Can the scalar be expressed in the literal or folded styles?
+ pub block_allowed: bool,
+ /// The output style.
+ pub style: yaml_scalar_style_t,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+pub(crate) struct yaml_string_t {
+ pub start: *mut yaml_char_t,
+ pub end: *mut yaml_char_t,
+ pub pointer: *mut yaml_char_t,
+}
+
+pub(crate) const NULL_STRING: yaml_string_t = yaml_string_t {
+ start: ptr::null_mut::<yaml_char_t>(),
+ end: ptr::null_mut::<yaml_char_t>(),
+ pointer: ptr::null_mut::<yaml_char_t>(),
+};
+
+#[repr(C)]
+pub(crate) struct yaml_buffer_t<T> {
+ /// The beginning of the buffer.
+ pub start: *mut T,
+ /// The end of the buffer.
+ pub end: *mut T,
+ /// The current position of the buffer.
+ pub pointer: *mut T,
+ /// The last filled position of the buffer.
+ pub last: *mut T,
+}
+
+impl<T> Copy for yaml_buffer_t<T> {}
+impl<T> Clone for yaml_buffer_t<T> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+#[repr(C)]
+pub struct yaml_stack_t<T> {
+ /// The beginning of the stack.
+ pub start: *mut T,
+ /// The end of the stack.
+ pub end: *mut T,
+ /// The top of the stack.
+ pub top: *mut T,
+}
+
+impl<T> Copy for yaml_stack_t<T> {}
+impl<T> Clone for yaml_stack_t<T> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
+#[repr(C)]
+pub(crate) struct yaml_queue_t<T> {
+ /// The beginning of the queue.
+ pub start: *mut T,
+ /// The end of the queue.
+ pub end: *mut T,
+ /// The head of the queue.
+ pub head: *mut T,
+ /// The tail of the queue.
+ pub tail: *mut T,
+}
+
+impl<T> Copy for yaml_queue_t<T> {}
+impl<T> Clone for yaml_queue_t<T> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
diff --git a/tests/bin/mod.rs b/tests/bin/mod.rs
new file mode 100644
index 0000000..0500980
--- /dev/null
+++ b/tests/bin/mod.rs
@@ -0,0 +1,48 @@
+use std::error::Error;
+use std::fs::File;
+use std::io::{Read, Write};
+use std::path::Path;
+use std::process::{Command, Stdio};
+
+pub struct Output {
+ pub success: bool,
+ pub stdout: Vec<u8>,
+ pub stderr: Vec<u8>,
+}
+
+pub fn run(
+ compiled: &str,
+ unsafe_main: unsafe fn(
+ stdin: &mut dyn Read,
+ stdout: &mut dyn Write,
+ ) -> Result<(), Box<dyn Error>>,
+ input: &Path,
+) -> Output {
+ if cfg!(miri) {
+ let mut input = File::open(input).unwrap();
+ let mut stdout = Vec::new();
+ let result = unsafe { unsafe_main(&mut input, &mut stdout) };
+
+ Output {
+ success: result.is_ok(),
+ stdout,
+ stderr: result
+ .err()
+ .as_ref()
+ .map_or_else(String::new, ToString::to_string)
+ .into(),
+ }
+ } else {
+ let output = Command::new(compiled)
+ .arg(input)
+ .stdin(Stdio::null())
+ .output()
+ .unwrap();
+
+ Output {
+ success: output.status.success(),
+ stdout: output.stdout,
+ stderr: output.stderr,
+ }
+ }
+}
diff --git a/tests/ignorelist/libyaml-emitter b/tests/ignorelist/libyaml-emitter
new file mode 100644
index 0000000..b52000f
--- /dev/null
+++ b/tests/ignorelist/libyaml-emitter
@@ -0,0 +1,72 @@
+26DV: Whitespace around colon in mappings
+2EBW: Allowed characters in keys
+2JQS: Block Mapping with Missing Keys
+2LFX: Spec Example 6.13. Reserved Directives [1.3]
+2SXE: Anchors With Colon in Name
+2XXW: Spec Example 2.25. Unordered Sets
+3MYT: Plain Scalar looking like key, comment, anchor and tag
+4ABK: Spec Example 7.17. Flow Mapping Separate Values
+4MUZ: Flow mapping colon on line after key
+4QFQ: Spec Example 8.2. Block Indentation Indicator [1.3]
+52DL: Explicit Non-Specific Tag [1.3]
+565N: Construct Binary
+5TYM: Spec Example 6.21. Local Tag Prefix
+5WE3: Spec Example 8.17. Explicit Block Mapping Entries
+6CK3: Spec Example 6.26. Tag Shorthands
+6FWR: Block Scalar Keep
+6KGN: Anchor for empty node
+6M2F: Aliases in Explicit Block Mapping
+6PBE: Zero-indented sequences in explicit mapping keys
+6SLA: Allowed characters in quoted mapping key
+6WLZ: Spec Example 6.18. Primary Tag Handle [1.3]
+6WPF: Spec Example 6.8. Flow Folding [1.3]
+6XDY: Two document start markers
+6ZKB: Spec Example 9.6. Stream
+7T8X: Spec Example 8.10. Folded Lines - 8.13. Final Empty Lines
+7W2P: Block Mapping with Missing Values
+7Z25: Bare document after document end marker
+8KB6: Multiline plain flow mapping key without value
+8XYN: Anchor with unicode character
+9BXH: Multiline doublequoted flow mapping key without value
+8MK2: Explicit Non-Specific Tag
+9DXL: Spec Example 9.6. Stream [1.3]
+9MMW: Spec Example 7.21. Single Pair Implicit Entries [1.3
+9TFX: Spec Example 7.6. Double Quoted Lines [1.3]
+B3HG: Spec Example 8.9. Folded Scalar [1.3]
+C2DT: Spec Example 7.18. Flow Mapping Adjacent Values
+DFF7: Spec Example 7.16. Flow Mapping Entries
+E76Z: Aliases in Implicit Block Mapping
+EX5H: Multiline Scalar at Top Level [1.3]
+EXG3: Three dashes and content without space [1.3]
+FBC9: Allowed characters in plain scalars
+FH7J: Tags on Empty Scalars
+FRK4: Spec Example 7.3. Completely Empty Flow Nodes
+J3BT: Spec Example 5.12. Tabs and Spaces
+JDH8: Plain Scalar looking like key, comment, anchor and tag [1.3]
+JTV5: Block Mapping with Multiline Scalars
+K54U: Tab after document header
+KK5P: Various combinations of explicit block mappings
+KSS4: Scalars on --- line
+KZN9: Spec Example 7.21. Single Pair Implicit Entries
+LE5A: Spec Example 7.24. Flow Nodes
+M7A3: Spec Example 9.3. Bare Documents
+M9B4: Spec Example 8.7. Literal Scalar
+NAT4: Various empty or newline only quoted strings
+NHX8: Empty Lines at End of Document
+PUW8: Document start on last line
+PW8X: Anchors on Empty Scalars
+Q8AD: Spec Example 7.5. Double Quoted Line Breaks [1.3]
+S3PD: Spec Example 8.18. Implicit Block Mapping Entries
+S4JQ: Spec Example 6.28. Non-Specific Tags
+T26H: Spec Example 8.8. Literal Content [1.3]
+T4YY: Spec Example 7.9. Single Quoted Lines [1.3]
+T5N4: Spec Example 8.7. Literal Scalar [1.3]
+UT92: Spec Example 9.4. Explicit Documents
+W42U: Spec Example 8.15. Block Sequence Entry Types
+W4TN: Spec Example 9.5. Directives Documents
+W5VH: Allowed characters in alias
+WZ62: Spec Example 7.2. Empty Content
+X38W: Aliases in Flow Objects
+XLQ9: Multiline scalar that looks like a YAML directive
+Y2GN: Anchor with colon in the middle
+ZWK4: Key with anchor after missing explicit mapping value
diff --git a/tests/ignorelist/libyaml-parser b/tests/ignorelist/libyaml-parser
new file mode 100644
index 0000000..94029f6
--- /dev/null
+++ b/tests/ignorelist/libyaml-parser
@@ -0,0 +1,34 @@
+2JQS: Block Mapping with Missing Keys
+2LFX: Spec Example 6.13. Reserved Directives [1.3]
+2SXE: Anchors With Colon in Name
+4ABK: Spec Example 7.17. Flow Mapping Separate Values
+4MUZ: Flow mapping colon on line after key
+5MUD: Colon and adjacent value on next line
+6BCT: Spec Example 6.3. Separation Spaces
+6LVF: Spec Example 6.13. Reserved Directives
+6M2F: Aliases in Explicit Block Mapping
+7Z25: Bare document after document end marker
+8XYN: Anchor with unicode character
+9MMW: Spec Example 7.21. Single Pair Implicit Entries [1.3
+9SA2: Multiline double quoted flow mapping key
+A2M4: Spec Example 6.2. Indentation Indicators
+BEC7: Spec Example 6.14. “YAML” directive
+DBG4: Spec Example 7.10. Plain Characters
+DK3J: Zero indented block scalar with line that looks like a comment
+FP8R: Zero indented block scalar
+FRK4: Spec Example 7.3. Completely Empty Flow Nodes
+HWV9: Document-end marker
+K3WX: Colon and adjacent value after comment on next line
+KZN9: Spec Example 7.21. Single Pair Implicit Entries
+M7A3: Spec Example 9.3. Bare Documents
+NHX8: Empty Lines at End of Document
+NJ66: Multiline plain flow mapping key
+Q5MG: Tab at beginning of line followed by a flow mapping
+QT73: Comment and document-end marker
+R4YG: Spec Example 8.2. Block Indentation Indicator
+S3PD: Spec Example 8.18. Implicit Block Mapping Entries
+UT92: Spec Example 9.4. Explicit Documents
+W4TN: Spec Example 9.5. Directives Documents
+W5VH: Allowed characters in alias
+WZ62: Spec Example 7.2. Empty Content
+Y2GN: Anchor with colon in the middle
diff --git a/tests/ignorelist/libyaml-parser-error b/tests/ignorelist/libyaml-parser-error
new file mode 100644
index 0000000..aa83f1a
--- /dev/null
+++ b/tests/ignorelist/libyaml-parser-error
@@ -0,0 +1,10 @@
+9C9N: Wrong indented flow sequence
+9HCY: Need document footer before directives
+9JBA: Invalid comment after end of flow sequence
+CVW2: Invalid comment after comma
+EB22: Missing document-end marker before directive
+QB6E: Wrong indented multiline quoted scalar
+RHX7: YAML directive without document end marker
+S98Z: Block scalar with more spaces than first content line
+SU5Z: Comment without whitespace after doublequoted scalar
+X4QW: Comment without whitespace after block scalar indicator
diff --git a/tests/test_emitter.rs b/tests/test_emitter.rs
new file mode 100644
index 0000000..852be2c
--- /dev/null
+++ b/tests/test_emitter.rs
@@ -0,0 +1,37 @@
+#![allow(clippy::type_complexity)]
+
+mod bin;
+#[path = "../src/bin/run-emitter-test-suite.rs"]
+#[allow(dead_code)]
+mod run_emitter_test_suite;
+
+use std::fs;
+use std::path::Path;
+
+fn test(id: &str) {
+ let dir = Path::new("tests")
+ .join("data")
+ .join("yaml-test-suite")
+ .join(id);
+
+ let output = bin::run(
+ env!("CARGO_BIN_EXE_run-emitter-test-suite"),
+ run_emitter_test_suite::unsafe_main,
+ &dir.join("test.event"),
+ );
+
+ let stdout = String::from_utf8_lossy(&output.stdout);
+ let stderr = String::from_utf8_lossy(&output.stderr);
+ eprint!("{}", stderr);
+
+ let out = if dir.join("out.yaml").exists() {
+ dir.join("out.yaml")
+ } else {
+ dir.join("in.yaml")
+ };
+ let expected = fs::read_to_string(out).unwrap();
+ pretty_assertions::assert_str_eq!(expected, stdout);
+ assert!(output.success);
+}
+
+unsafe_libyaml_test_suite::test_emitter!();
diff --git a/tests/test_parser.rs b/tests/test_parser.rs
new file mode 100644
index 0000000..190db26
--- /dev/null
+++ b/tests/test_parser.rs
@@ -0,0 +1,32 @@
+#![allow(clippy::type_complexity)]
+
+mod bin;
+#[path = "../src/bin/run-parser-test-suite.rs"]
+#[allow(dead_code)]
+mod run_parser_test_suite;
+
+use std::fs;
+use std::path::Path;
+
+fn test(id: &str) {
+ let dir = Path::new("tests")
+ .join("data")
+ .join("yaml-test-suite")
+ .join(id);
+
+ let output = bin::run(
+ env!("CARGO_BIN_EXE_run-parser-test-suite"),
+ run_parser_test_suite::unsafe_main,
+ &dir.join("in.yaml"),
+ );
+
+ let stdout = String::from_utf8_lossy(&output.stdout);
+ let stderr = String::from_utf8_lossy(&output.stderr);
+ eprint!("{}", stderr);
+
+ let expected = fs::read_to_string(dir.join("test.event")).unwrap();
+ pretty_assertions::assert_str_eq!(expected, stdout);
+ assert!(output.success);
+}
+
+unsafe_libyaml_test_suite::test_parser!();
diff --git a/tests/test_parser_error.rs b/tests/test_parser_error.rs
new file mode 100644
index 0000000..9473de8
--- /dev/null
+++ b/tests/test_parser_error.rs
@@ -0,0 +1,31 @@
+#![allow(clippy::type_complexity)]
+
+mod bin;
+#[path = "../src/bin/run-parser-test-suite.rs"]
+#[allow(dead_code)]
+mod run_parser_test_suite;
+
+use std::path::Path;
+
+fn test(id: &str) {
+ let dir = Path::new("tests")
+ .join("data")
+ .join("yaml-test-suite")
+ .join(id);
+
+ let output = bin::run(
+ env!("CARGO_BIN_EXE_run-parser-test-suite"),
+ run_parser_test_suite::unsafe_main,
+ &dir.join("in.yaml"),
+ );
+
+ if output.success {
+ let stdout = String::from_utf8_lossy(&output.stdout);
+ let stderr = String::from_utf8_lossy(&output.stderr);
+ eprint!("{}", stdout);
+ eprint!("{}", stderr);
+ panic!("expected parse to fail");
+ }
+}
+
+unsafe_libyaml_test_suite::test_parser_error!();