mirror of
https://github.com/simonask/libyaml-safer
synced 2024-11-26 05:10:20 +00:00
Emitter: Safe event analysis
This commit is contained in:
parent
8f7ec75545
commit
11b47abdb7
3 changed files with 289 additions and 309 deletions
507
src/emitter.rs
507
src/emitter.rs
|
@ -4,8 +4,8 @@ use crate::api::OUTPUT_BUFFER_SIZE;
|
|||
use crate::macros::{
|
||||
is_alpha, is_ascii, is_blank, is_blankz, is_bom, is_break, is_printable, is_space,
|
||||
};
|
||||
use crate::ops::{ForceAdd as _, ForceMul as _};
|
||||
use crate::yaml::{size_t, yaml_char_t, YamlEventData};
|
||||
use crate::ops::ForceMul as _;
|
||||
use crate::yaml::YamlEventData;
|
||||
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, YAML_ANY_BREAK, YAML_ANY_ENCODING,
|
||||
|
@ -22,7 +22,6 @@ use crate::{
|
|||
YAML_FOLDED_SCALAR_STYLE, YAML_LITERAL_SCALAR_STYLE, YAML_LN_BREAK, YAML_PLAIN_SCALAR_STYLE,
|
||||
YAML_SINGLE_QUOTED_SCALAR_STYLE, YAML_UTF8_ENCODING,
|
||||
};
|
||||
use core::ptr::{self};
|
||||
|
||||
unsafe fn FLUSH(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
if emitter.buffer.len() < OUTPUT_BUFFER_SIZE - 5 {
|
||||
|
@ -82,6 +81,40 @@ unsafe fn WRITE_BREAK_CHAR(emitter: &mut yaml_emitter_t, ch: char) -> Result<(),
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Analysis<'a> {
|
||||
pub anchor: Option<AnchorAnalysis<'a>>,
|
||||
pub tag: Option<TagAnalysis<'a>>,
|
||||
pub scalar: Option<ScalarAnalysis<'a>>,
|
||||
}
|
||||
|
||||
struct AnchorAnalysis<'a> {
|
||||
pub anchor: &'a str,
|
||||
pub alias: bool,
|
||||
}
|
||||
|
||||
struct TagAnalysis<'a> {
|
||||
pub handle: &'a str,
|
||||
pub suffix: &'a str,
|
||||
}
|
||||
|
||||
struct ScalarAnalysis<'a> {
|
||||
/// The scalar value.
|
||||
pub value: &'a str,
|
||||
/// 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,
|
||||
}
|
||||
|
||||
fn yaml_emitter_set_emitter_error(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
problem: &'static str,
|
||||
|
@ -103,9 +136,17 @@ pub unsafe fn yaml_emitter_emit(
|
|||
) -> Result<(), ()> {
|
||||
emitter.events.push_back(event);
|
||||
while let Some(mut event) = yaml_emitter_needs_mode_events(emitter) {
|
||||
yaml_emitter_analyze_event(emitter, &event)?;
|
||||
yaml_emitter_state_machine(emitter, &event)?;
|
||||
let tag_directives = core::mem::take(&mut emitter.tag_directives);
|
||||
|
||||
let mut analysis = yaml_emitter_analyze_event(emitter, &event, &tag_directives)?;
|
||||
yaml_emitter_state_machine(emitter, &event, &mut analysis)?;
|
||||
yaml_event_delete(&mut event);
|
||||
|
||||
// The DOCUMENT-START event populates the tag directives, and this
|
||||
// happens only once, so don't swap out the tags in that case.
|
||||
if emitter.tag_directives.is_empty() {
|
||||
emitter.tag_directives = tag_directives;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -180,6 +221,7 @@ unsafe fn yaml_emitter_increase_indent(emitter: &mut yaml_emitter_t, flow: bool,
|
|||
unsafe fn yaml_emitter_state_machine(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
match emitter.state {
|
||||
YAML_EMIT_STREAM_START_STATE => yaml_emitter_emit_stream_start(emitter, event),
|
||||
|
@ -187,43 +229,45 @@ unsafe fn yaml_emitter_state_machine(
|
|||
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_CONTENT_STATE => {
|
||||
yaml_emitter_emit_document_content(emitter, event, analysis)
|
||||
}
|
||||
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_emitter_emit_flow_sequence_item(emitter, event, true, analysis)
|
||||
}
|
||||
YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE => {
|
||||
yaml_emitter_emit_flow_sequence_item(emitter, event, false)
|
||||
yaml_emitter_emit_flow_sequence_item(emitter, event, false, analysis)
|
||||
}
|
||||
YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE => {
|
||||
yaml_emitter_emit_flow_mapping_key(emitter, event, true)
|
||||
yaml_emitter_emit_flow_mapping_key(emitter, event, true, analysis)
|
||||
}
|
||||
YAML_EMIT_FLOW_MAPPING_KEY_STATE => {
|
||||
yaml_emitter_emit_flow_mapping_key(emitter, event, false)
|
||||
yaml_emitter_emit_flow_mapping_key(emitter, event, false, analysis)
|
||||
}
|
||||
YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE => {
|
||||
yaml_emitter_emit_flow_mapping_value(emitter, event, true)
|
||||
yaml_emitter_emit_flow_mapping_value(emitter, event, true, analysis)
|
||||
}
|
||||
YAML_EMIT_FLOW_MAPPING_VALUE_STATE => {
|
||||
yaml_emitter_emit_flow_mapping_value(emitter, event, false)
|
||||
yaml_emitter_emit_flow_mapping_value(emitter, event, false, analysis)
|
||||
}
|
||||
YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE => {
|
||||
yaml_emitter_emit_block_sequence_item(emitter, event, true)
|
||||
yaml_emitter_emit_block_sequence_item(emitter, event, true, analysis)
|
||||
}
|
||||
YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE => {
|
||||
yaml_emitter_emit_block_sequence_item(emitter, event, false)
|
||||
yaml_emitter_emit_block_sequence_item(emitter, event, false, analysis)
|
||||
}
|
||||
YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE => {
|
||||
yaml_emitter_emit_block_mapping_key(emitter, event, true)
|
||||
yaml_emitter_emit_block_mapping_key(emitter, event, true, analysis)
|
||||
}
|
||||
YAML_EMIT_BLOCK_MAPPING_KEY_STATE => {
|
||||
yaml_emitter_emit_block_mapping_key(emitter, event, false)
|
||||
yaml_emitter_emit_block_mapping_key(emitter, event, false, analysis)
|
||||
}
|
||||
YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE => {
|
||||
yaml_emitter_emit_block_mapping_value(emitter, event, true)
|
||||
yaml_emitter_emit_block_mapping_value(emitter, event, true, analysis)
|
||||
}
|
||||
YAML_EMIT_BLOCK_MAPPING_VALUE_STATE => {
|
||||
yaml_emitter_emit_block_mapping_value(emitter, event, false)
|
||||
yaml_emitter_emit_block_mapping_value(emitter, event, false, analysis)
|
||||
}
|
||||
YAML_EMIT_END_STATE => {
|
||||
yaml_emitter_set_emitter_error(emitter, "expected nothing after STREAM-END")
|
||||
|
@ -362,9 +406,10 @@ unsafe fn yaml_emitter_emit_document_start(
|
|||
unsafe fn yaml_emitter_emit_document_content(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
emitter.states.push(YAML_EMIT_DOCUMENT_END_STATE);
|
||||
yaml_emitter_emit_node(emitter, event, true, false, false, false)
|
||||
yaml_emitter_emit_node(emitter, event, true, false, false, false, analysis)
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_emit_document_end(
|
||||
|
@ -394,6 +439,7 @@ unsafe fn yaml_emitter_emit_flow_sequence_item(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
first: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
if first {
|
||||
yaml_emitter_write_indicator(emitter, "[", true, true, false)?;
|
||||
|
@ -418,13 +464,14 @@ unsafe fn yaml_emitter_emit_flow_sequence_item(
|
|||
yaml_emitter_write_indent(emitter)?;
|
||||
}
|
||||
emitter.states.push(YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE);
|
||||
yaml_emitter_emit_node(emitter, event, false, true, false, false)
|
||||
yaml_emitter_emit_node(emitter, event, false, true, false, false, analysis)
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_emit_flow_mapping_key(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
first: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
if first {
|
||||
yaml_emitter_write_indicator(emitter, "{", true, true, false)?;
|
||||
|
@ -451,15 +498,15 @@ unsafe fn yaml_emitter_emit_flow_mapping_key(
|
|||
if emitter.canonical || emitter.column > emitter.best_width {
|
||||
yaml_emitter_write_indent(emitter)?;
|
||||
}
|
||||
if !emitter.canonical && yaml_emitter_check_simple_key(emitter, event) {
|
||||
if !emitter.canonical && yaml_emitter_check_simple_key(emitter, event, analysis) {
|
||||
emitter
|
||||
.states
|
||||
.push(YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE);
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, true)
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, true, analysis)
|
||||
} else {
|
||||
yaml_emitter_write_indicator(emitter, "?", true, false, false)?;
|
||||
emitter.states.push(YAML_EMIT_FLOW_MAPPING_VALUE_STATE);
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, false)
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, false, analysis)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,6 +514,7 @@ unsafe fn yaml_emitter_emit_flow_mapping_value(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
simple: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
if simple {
|
||||
yaml_emitter_write_indicator(emitter, ":", false, false, false)?;
|
||||
|
@ -477,13 +525,14 @@ unsafe fn yaml_emitter_emit_flow_mapping_value(
|
|||
yaml_emitter_write_indicator(emitter, ":", true, false, false)?;
|
||||
}
|
||||
emitter.states.push(YAML_EMIT_FLOW_MAPPING_KEY_STATE);
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, false)
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, false, analysis)
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_emit_block_sequence_item(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
first: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
if first {
|
||||
yaml_emitter_increase_indent(
|
||||
|
@ -500,13 +549,14 @@ unsafe fn yaml_emitter_emit_block_sequence_item(
|
|||
yaml_emitter_write_indent(emitter)?;
|
||||
yaml_emitter_write_indicator(emitter, "-", true, false, true)?;
|
||||
emitter.states.push(YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE);
|
||||
yaml_emitter_emit_node(emitter, event, false, true, false, false)
|
||||
yaml_emitter_emit_node(emitter, event, false, true, false, false, analysis)
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_emit_block_mapping_key(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
first: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
if first {
|
||||
yaml_emitter_increase_indent(emitter, false, false);
|
||||
|
@ -517,15 +567,15 @@ unsafe fn yaml_emitter_emit_block_mapping_key(
|
|||
return Ok(());
|
||||
}
|
||||
yaml_emitter_write_indent(emitter)?;
|
||||
if yaml_emitter_check_simple_key(emitter, event) {
|
||||
if yaml_emitter_check_simple_key(emitter, event, analysis) {
|
||||
emitter
|
||||
.states
|
||||
.push(YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE);
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, true)
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, true, analysis)
|
||||
} else {
|
||||
yaml_emitter_write_indicator(emitter, "?", true, false, true)?;
|
||||
emitter.states.push(YAML_EMIT_BLOCK_MAPPING_VALUE_STATE);
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, false)
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, false, analysis)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -533,6 +583,7 @@ unsafe fn yaml_emitter_emit_block_mapping_value(
|
|||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
simple: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
if simple {
|
||||
yaml_emitter_write_indicator(emitter, ":", false, false, false)?;
|
||||
|
@ -541,7 +592,7 @@ unsafe fn yaml_emitter_emit_block_mapping_value(
|
|||
yaml_emitter_write_indicator(emitter, ":", true, false, true)?;
|
||||
}
|
||||
emitter.states.push(YAML_EMIT_BLOCK_MAPPING_KEY_STATE);
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, false)
|
||||
yaml_emitter_emit_node(emitter, event, false, false, true, false, analysis)
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_emit_node(
|
||||
|
@ -551,6 +602,7 @@ unsafe fn yaml_emitter_emit_node(
|
|||
sequence: bool,
|
||||
mapping: bool,
|
||||
simple_key: bool,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
emitter.root_context = root;
|
||||
emitter.sequence_context = sequence;
|
||||
|
@ -558,10 +610,14 @@ unsafe fn yaml_emitter_emit_node(
|
|||
emitter.simple_key_context = simple_key;
|
||||
|
||||
match event.data {
|
||||
YamlEventData::Alias { .. } => yaml_emitter_emit_alias(emitter, event),
|
||||
YamlEventData::Scalar { .. } => yaml_emitter_emit_scalar(emitter, event),
|
||||
YamlEventData::SequenceStart { .. } => yaml_emitter_emit_sequence_start(emitter, event),
|
||||
YamlEventData::MappingStart { .. } => yaml_emitter_emit_mapping_start(emitter, event),
|
||||
YamlEventData::Alias { .. } => yaml_emitter_emit_alias(emitter, event, &analysis.anchor),
|
||||
YamlEventData::Scalar { .. } => yaml_emitter_emit_scalar(emitter, event, analysis),
|
||||
YamlEventData::SequenceStart { .. } => {
|
||||
yaml_emitter_emit_sequence_start(emitter, event, analysis)
|
||||
}
|
||||
YamlEventData::MappingStart { .. } => {
|
||||
yaml_emitter_emit_mapping_start(emitter, event, analysis)
|
||||
}
|
||||
_ => yaml_emitter_set_emitter_error(
|
||||
emitter,
|
||||
"expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS",
|
||||
|
@ -572,8 +628,9 @@ unsafe fn yaml_emitter_emit_node(
|
|||
unsafe fn yaml_emitter_emit_alias(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
_event: &yaml_event_t,
|
||||
analysis: &Option<AnchorAnalysis>,
|
||||
) -> Result<(), ()> {
|
||||
yaml_emitter_process_anchor(emitter)?;
|
||||
yaml_emitter_process_anchor(emitter, analysis)?;
|
||||
if emitter.simple_key_context {
|
||||
PUT(emitter, b' ')?;
|
||||
}
|
||||
|
@ -584,12 +641,22 @@ unsafe fn yaml_emitter_emit_alias(
|
|||
unsafe fn yaml_emitter_emit_scalar(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &mut Analysis,
|
||||
) -> Result<(), ()> {
|
||||
yaml_emitter_select_scalar_style(emitter, event)?;
|
||||
yaml_emitter_process_anchor(emitter)?;
|
||||
yaml_emitter_process_tag(emitter)?;
|
||||
let Analysis {
|
||||
anchor,
|
||||
tag,
|
||||
scalar: Some(scalar),
|
||||
} = analysis
|
||||
else {
|
||||
unreachable!("no scalar analysis");
|
||||
};
|
||||
|
||||
yaml_emitter_select_scalar_style(emitter, event, scalar, tag)?;
|
||||
yaml_emitter_process_anchor(emitter, anchor)?;
|
||||
yaml_emitter_process_tag(emitter, tag)?;
|
||||
yaml_emitter_increase_indent(emitter, true, false);
|
||||
yaml_emitter_process_scalar(emitter)?;
|
||||
yaml_emitter_process_scalar(emitter, scalar)?;
|
||||
emitter.indent = emitter.indents.pop().unwrap();
|
||||
emitter.state = emitter.states.pop().unwrap();
|
||||
Ok(())
|
||||
|
@ -598,9 +665,11 @@ unsafe fn yaml_emitter_emit_scalar(
|
|||
unsafe fn yaml_emitter_emit_sequence_start(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &Analysis,
|
||||
) -> Result<(), ()> {
|
||||
yaml_emitter_process_anchor(emitter)?;
|
||||
yaml_emitter_process_tag(emitter)?;
|
||||
let Analysis { anchor, tag, .. } = analysis;
|
||||
yaml_emitter_process_anchor(emitter, anchor)?;
|
||||
yaml_emitter_process_tag(emitter, tag)?;
|
||||
|
||||
let style = if let YamlEventData::SequenceStart { style, .. } = &event.data {
|
||||
*style
|
||||
|
@ -623,9 +692,11 @@ unsafe fn yaml_emitter_emit_sequence_start(
|
|||
unsafe fn yaml_emitter_emit_mapping_start(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &Analysis,
|
||||
) -> Result<(), ()> {
|
||||
yaml_emitter_process_anchor(emitter)?;
|
||||
yaml_emitter_process_tag(emitter)?;
|
||||
let Analysis { anchor, tag, .. } = analysis;
|
||||
yaml_emitter_process_anchor(emitter, anchor)?;
|
||||
yaml_emitter_process_tag(emitter, tag)?;
|
||||
|
||||
let style = if let YamlEventData::MappingStart { style, .. } = &event.data {
|
||||
*style
|
||||
|
@ -649,10 +720,7 @@ unsafe fn yaml_emitter_check_empty_document(_emitter: &yaml_emitter_t) -> bool {
|
|||
false
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_check_empty_sequence(
|
||||
emitter: &yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
) -> bool {
|
||||
fn yaml_emitter_check_empty_sequence(emitter: &yaml_emitter_t, event: &yaml_event_t) -> bool {
|
||||
if emitter.events.len() < 1 {
|
||||
return false;
|
||||
}
|
||||
|
@ -669,7 +737,7 @@ unsafe fn yaml_emitter_check_empty_sequence(
|
|||
start && end
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_check_empty_mapping(emitter: &yaml_emitter_t, event: &yaml_event_t) -> bool {
|
||||
fn yaml_emitter_check_empty_mapping(emitter: &yaml_emitter_t, event: &yaml_event_t) -> bool {
|
||||
if emitter.events.len() < 1 {
|
||||
return false;
|
||||
}
|
||||
|
@ -686,46 +754,55 @@ unsafe fn yaml_emitter_check_empty_mapping(emitter: &yaml_emitter_t, event: &yam
|
|||
start && end
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_check_simple_key(emitter: &yaml_emitter_t, event: &yaml_event_t) -> bool {
|
||||
let mut length: size_t = 0_u64;
|
||||
fn yaml_emitter_check_simple_key(
|
||||
emitter: &yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
analysis: &Analysis,
|
||||
) -> bool {
|
||||
let Analysis {
|
||||
tag,
|
||||
anchor,
|
||||
scalar,
|
||||
} = analysis;
|
||||
|
||||
let mut length = anchor.as_ref().map(|a| a.anchor.len()).unwrap_or(0)
|
||||
+ tag
|
||||
.as_ref()
|
||||
.map(|t| t.handle.len() + t.suffix.len())
|
||||
.unwrap_or(0);
|
||||
|
||||
match event.data {
|
||||
YamlEventData::Alias { .. } => {
|
||||
length =
|
||||
(length as libc::c_ulong).force_add(emitter.anchor_data.anchor_length) as size_t;
|
||||
length = analysis
|
||||
.anchor
|
||||
.as_ref()
|
||||
.map(|a| a.anchor.len())
|
||||
.unwrap_or(0);
|
||||
}
|
||||
YamlEventData::Scalar { .. } => {
|
||||
if emitter.scalar_data.multiline {
|
||||
let Some(scalar) = scalar else {
|
||||
panic!("no analysis for scalar")
|
||||
};
|
||||
|
||||
if scalar.multiline {
|
||||
return false;
|
||||
}
|
||||
length = (length as libc::c_ulong)
|
||||
.force_add(emitter.anchor_data.anchor_length)
|
||||
.force_add(emitter.tag_data.handle_length)
|
||||
.force_add(emitter.tag_data.suffix_length)
|
||||
.force_add(emitter.scalar_data.length) as size_t;
|
||||
length += scalar.value.len();
|
||||
}
|
||||
YamlEventData::SequenceStart { .. } => {
|
||||
if !yaml_emitter_check_empty_sequence(emitter, event) {
|
||||
return false;
|
||||
}
|
||||
length = (length as libc::c_ulong)
|
||||
.force_add(emitter.anchor_data.anchor_length)
|
||||
.force_add(emitter.tag_data.handle_length)
|
||||
.force_add(emitter.tag_data.suffix_length) as size_t;
|
||||
}
|
||||
YamlEventData::MappingStart { .. } => {
|
||||
if !yaml_emitter_check_empty_mapping(emitter, event) {
|
||||
return false;
|
||||
}
|
||||
length = (length as libc::c_ulong)
|
||||
.force_add(emitter.anchor_data.anchor_length)
|
||||
.force_add(emitter.tag_data.handle_length)
|
||||
.force_add(emitter.tag_data.suffix_length) as size_t;
|
||||
}
|
||||
_ => return false,
|
||||
}
|
||||
|
||||
if length > 128_u64 {
|
||||
if length > 128 {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -735,6 +812,8 @@ unsafe fn yaml_emitter_check_simple_key(emitter: &yaml_emitter_t, event: &yaml_e
|
|||
unsafe fn yaml_emitter_select_scalar_style(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
scalar_analysis: &mut ScalarAnalysis,
|
||||
tag_analysis: &mut Option<TagAnalysis>,
|
||||
) -> Result<(), ()> {
|
||||
if let YamlEventData::Scalar {
|
||||
plain_implicit,
|
||||
|
@ -744,12 +823,12 @@ unsafe fn yaml_emitter_select_scalar_style(
|
|||
} = &event.data
|
||||
{
|
||||
let mut style: yaml_scalar_style_t = *style;
|
||||
let no_tag = emitter.tag_data.handle.is_null() && emitter.tag_data.suffix.is_null();
|
||||
let no_tag = tag_analysis.is_none();
|
||||
if no_tag && !*plain_implicit && !*quoted_implicit {
|
||||
return yaml_emitter_set_emitter_error(
|
||||
yaml_emitter_set_emitter_error(
|
||||
emitter,
|
||||
"neither tag nor implicit flags are specified",
|
||||
);
|
||||
)?;
|
||||
}
|
||||
if style == YAML_ANY_SCALAR_STYLE {
|
||||
style = YAML_PLAIN_SCALAR_STYLE;
|
||||
|
@ -757,16 +836,16 @@ unsafe fn yaml_emitter_select_scalar_style(
|
|||
if emitter.canonical {
|
||||
style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
|
||||
}
|
||||
if emitter.simple_key_context && emitter.scalar_data.multiline {
|
||||
if emitter.simple_key_context && scalar_analysis.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
|
||||
if emitter.flow_level != 0 && !scalar_analysis.flow_plain_allowed
|
||||
|| emitter.flow_level == 0 && !scalar_analysis.block_plain_allowed
|
||||
{
|
||||
style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
|
||||
}
|
||||
if emitter.scalar_data.length == 0
|
||||
if scalar_analysis.value.is_empty()
|
||||
&& (emitter.flow_level != 0 || emitter.simple_key_context)
|
||||
{
|
||||
style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
|
||||
|
@ -776,12 +855,12 @@ unsafe fn yaml_emitter_select_scalar_style(
|
|||
}
|
||||
}
|
||||
if style == YAML_SINGLE_QUOTED_SCALAR_STYLE {
|
||||
if !emitter.scalar_data.single_quoted_allowed {
|
||||
if !scalar_analysis.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
|
||||
if !scalar_analysis.block_allowed
|
||||
|| emitter.flow_level != 0
|
||||
|| emitter.simple_key_context
|
||||
{
|
||||
|
@ -789,123 +868,90 @@ unsafe fn yaml_emitter_select_scalar_style(
|
|||
}
|
||||
}
|
||||
if no_tag && !*quoted_implicit && style != YAML_PLAIN_SCALAR_STYLE {
|
||||
emitter.tag_data.handle =
|
||||
b"!\0" as *const u8 as *const libc::c_char as *mut yaml_char_t;
|
||||
emitter.tag_data.handle_length = 1_u64;
|
||||
*tag_analysis = Some(TagAnalysis {
|
||||
handle: "!",
|
||||
suffix: "",
|
||||
});
|
||||
}
|
||||
emitter.scalar_data.style = style;
|
||||
scalar_analysis.style = style;
|
||||
Ok(())
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_process_anchor(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
if emitter.anchor_data.anchor.is_null() {
|
||||
unsafe fn yaml_emitter_process_anchor(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
analysis: &Option<AnchorAnalysis>,
|
||||
) -> Result<(), ()> {
|
||||
let Some(analysis) = analysis.as_ref() else {
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
yaml_emitter_write_indicator(
|
||||
emitter,
|
||||
if emitter.anchor_data.alias { "*" } else { "&" },
|
||||
if analysis.alias { "*" } else { "&" },
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
)?;
|
||||
yaml_emitter_write_anchor(
|
||||
emitter,
|
||||
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
|
||||
emitter.anchor_data.anchor,
|
||||
emitter.anchor_data.anchor_length as _,
|
||||
)),
|
||||
)
|
||||
yaml_emitter_write_anchor(emitter, analysis.anchor)
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_process_tag(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
if emitter.tag_data.handle.is_null() && emitter.tag_data.suffix.is_null() {
|
||||
unsafe fn yaml_emitter_process_tag(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
analysis: &Option<TagAnalysis>,
|
||||
) -> Result<(), ()> {
|
||||
let Some(analysis) = analysis.as_ref() else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
if analysis.handle.is_empty() && analysis.suffix.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
if !emitter.tag_data.handle.is_null() {
|
||||
yaml_emitter_write_tag_handle(
|
||||
emitter,
|
||||
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
|
||||
emitter.tag_data.handle,
|
||||
emitter.tag_data.handle_length as _,
|
||||
)),
|
||||
)?;
|
||||
if !emitter.tag_data.suffix.is_null() {
|
||||
yaml_emitter_write_tag_content(
|
||||
emitter,
|
||||
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
|
||||
emitter.tag_data.suffix,
|
||||
emitter.tag_data.suffix_length as _,
|
||||
)),
|
||||
false,
|
||||
)?;
|
||||
if !analysis.handle.is_empty() {
|
||||
yaml_emitter_write_tag_handle(emitter, analysis.handle)?;
|
||||
if !analysis.suffix.is_empty() {
|
||||
yaml_emitter_write_tag_content(emitter, analysis.suffix, false)?;
|
||||
}
|
||||
} else {
|
||||
yaml_emitter_write_indicator(emitter, "!<", true, false, false)?;
|
||||
yaml_emitter_write_tag_content(
|
||||
emitter,
|
||||
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
|
||||
emitter.tag_data.suffix,
|
||||
emitter.tag_data.suffix_length as _,
|
||||
)),
|
||||
false,
|
||||
)?;
|
||||
yaml_emitter_write_tag_content(emitter, analysis.suffix, false)?;
|
||||
yaml_emitter_write_indicator(emitter, ">", false, false, false)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_process_scalar(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
match emitter.scalar_data.style {
|
||||
unsafe fn yaml_emitter_process_scalar(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
analysis: &ScalarAnalysis,
|
||||
) -> Result<(), ()> {
|
||||
match analysis.style {
|
||||
YAML_PLAIN_SCALAR_STYLE => {
|
||||
return yaml_emitter_write_plain_scalar(
|
||||
emitter,
|
||||
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
|
||||
emitter.scalar_data.value,
|
||||
emitter.scalar_data.length as _,
|
||||
)),
|
||||
analysis.value,
|
||||
!emitter.simple_key_context,
|
||||
);
|
||||
}
|
||||
YAML_SINGLE_QUOTED_SCALAR_STYLE => {
|
||||
return yaml_emitter_write_single_quoted_scalar(
|
||||
emitter,
|
||||
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
|
||||
emitter.scalar_data.value,
|
||||
emitter.scalar_data.length as _,
|
||||
)),
|
||||
analysis.value,
|
||||
!emitter.simple_key_context,
|
||||
);
|
||||
}
|
||||
YAML_DOUBLE_QUOTED_SCALAR_STYLE => {
|
||||
return yaml_emitter_write_double_quoted_scalar(
|
||||
emitter,
|
||||
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
|
||||
emitter.scalar_data.value,
|
||||
emitter.scalar_data.length as _,
|
||||
)),
|
||||
analysis.value,
|
||||
!emitter.simple_key_context,
|
||||
);
|
||||
}
|
||||
YAML_LITERAL_SCALAR_STYLE => {
|
||||
return yaml_emitter_write_literal_scalar(
|
||||
emitter,
|
||||
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
|
||||
emitter.scalar_data.value,
|
||||
emitter.scalar_data.length as _,
|
||||
)),
|
||||
);
|
||||
return yaml_emitter_write_literal_scalar(emitter, analysis.value);
|
||||
}
|
||||
YAML_FOLDED_SCALAR_STYLE => {
|
||||
return yaml_emitter_write_folded_scalar(
|
||||
emitter,
|
||||
core::str::from_utf8_unchecked(core::slice::from_raw_parts(
|
||||
emitter.scalar_data.value,
|
||||
emitter.scalar_data.length as _,
|
||||
)),
|
||||
);
|
||||
return yaml_emitter_write_folded_scalar(emitter, analysis.value);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -955,63 +1001,66 @@ unsafe fn yaml_emitter_analyze_tag_directive(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_analyze_anchor(
|
||||
fn yaml_emitter_analyze_anchor<'a>(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
anchor: &str,
|
||||
anchor: &'a str,
|
||||
alias: bool,
|
||||
) -> Result<(), ()> {
|
||||
) -> Result<AnchorAnalysis<'a>, ()> {
|
||||
if anchor.is_empty() {
|
||||
return yaml_emitter_set_emitter_error(
|
||||
yaml_emitter_set_emitter_error(
|
||||
emitter,
|
||||
if alias {
|
||||
"alias value must not be empty"
|
||||
} else {
|
||||
"anchor value must not be empty"
|
||||
},
|
||||
);
|
||||
)?;
|
||||
}
|
||||
|
||||
for ch in anchor.chars() {
|
||||
if !IS_ALPHA_CHAR!(ch) {
|
||||
return yaml_emitter_set_emitter_error(
|
||||
yaml_emitter_set_emitter_error(
|
||||
emitter,
|
||||
if alias {
|
||||
"alias value must contain alphanumerical characters only"
|
||||
} else {
|
||||
"anchor value must contain alphanumerical characters only"
|
||||
},
|
||||
);
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
emitter.anchor_data.anchor = anchor.as_ptr();
|
||||
emitter.anchor_data.anchor_length = anchor.len() as _;
|
||||
emitter.anchor_data.alias = alias;
|
||||
Ok(())
|
||||
Ok(AnchorAnalysis { anchor, alias })
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_analyze_tag(emitter: &mut yaml_emitter_t, tag: &str) -> Result<(), ()> {
|
||||
fn yaml_emitter_analyze_tag<'a>(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
tag: &'a str,
|
||||
tag_directives: &'a [yaml_tag_directive_t],
|
||||
) -> Result<TagAnalysis<'a>, ()> {
|
||||
if tag.is_empty() {
|
||||
return yaml_emitter_set_emitter_error(emitter, "tag value must not be empty");
|
||||
yaml_emitter_set_emitter_error(emitter, "tag value must not be empty")?;
|
||||
}
|
||||
|
||||
for tag_directive in emitter.tag_directives.iter() {
|
||||
let mut handle = "";
|
||||
let mut suffix = tag;
|
||||
|
||||
for tag_directive in tag_directives.iter() {
|
||||
let prefix_len = tag_directive.prefix.len();
|
||||
if prefix_len < tag.len() && tag_directive.prefix == tag[0..prefix_len] {
|
||||
emitter.tag_data.handle = tag_directive.handle.as_ptr();
|
||||
emitter.tag_data.handle_length = tag_directive.handle.len() as _;
|
||||
let suffix = &tag[prefix_len..];
|
||||
emitter.tag_data.suffix = suffix.as_ptr();
|
||||
emitter.tag_data.suffix_length = suffix.len() as _;
|
||||
return Ok(());
|
||||
handle = &tag_directive.handle;
|
||||
suffix = &tag[prefix_len..];
|
||||
break;
|
||||
}
|
||||
}
|
||||
emitter.tag_data.suffix = tag.as_ptr();
|
||||
emitter.tag_data.suffix_length = tag.len() as _;
|
||||
Ok(())
|
||||
|
||||
Ok(TagAnalysis { handle, suffix })
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_analyze_scalar(emitter: &mut yaml_emitter_t, value: &str) -> Result<(), ()> {
|
||||
fn yaml_emitter_analyze_scalar<'a>(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
value: &'a str,
|
||||
) -> Result<ScalarAnalysis<'a>, ()> {
|
||||
let mut block_indicators = false;
|
||||
let mut flow_indicators = false;
|
||||
let mut line_breaks = false;
|
||||
|
@ -1026,16 +1075,16 @@ unsafe fn yaml_emitter_analyze_scalar(emitter: &mut yaml_emitter_t, value: &str)
|
|||
let mut previous_space = false;
|
||||
let mut previous_break = false;
|
||||
|
||||
emitter.scalar_data.value = value.as_ptr();
|
||||
emitter.scalar_data.length = value.len() as _;
|
||||
|
||||
if value.is_empty() {
|
||||
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(());
|
||||
return Ok(ScalarAnalysis {
|
||||
value: "",
|
||||
multiline: false,
|
||||
flow_plain_allowed: false,
|
||||
block_plain_allowed: true,
|
||||
single_quoted_allowed: true,
|
||||
block_allowed: false,
|
||||
style: YAML_ANY_SCALAR_STYLE,
|
||||
});
|
||||
}
|
||||
|
||||
if value.starts_with("---") || value.starts_with("...") {
|
||||
|
@ -1128,57 +1177,63 @@ unsafe fn yaml_emitter_analyze_scalar(emitter: &mut yaml_emitter_t, value: &str)
|
|||
first = false;
|
||||
}
|
||||
|
||||
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;
|
||||
let mut analysis = ScalarAnalysis {
|
||||
value,
|
||||
multiline: line_breaks,
|
||||
flow_plain_allowed: true,
|
||||
block_plain_allowed: true,
|
||||
single_quoted_allowed: true,
|
||||
block_allowed: true,
|
||||
style: YAML_ANY_SCALAR_STYLE,
|
||||
};
|
||||
|
||||
analysis.multiline = line_breaks;
|
||||
analysis.flow_plain_allowed = true;
|
||||
analysis.block_plain_allowed = true;
|
||||
analysis.single_quoted_allowed = true;
|
||||
analysis.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;
|
||||
analysis.flow_plain_allowed = false;
|
||||
analysis.block_plain_allowed = false;
|
||||
}
|
||||
if trailing_space {
|
||||
emitter.scalar_data.block_allowed = false;
|
||||
analysis.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;
|
||||
analysis.flow_plain_allowed = false;
|
||||
analysis.block_plain_allowed = false;
|
||||
analysis.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;
|
||||
analysis.flow_plain_allowed = false;
|
||||
analysis.block_plain_allowed = false;
|
||||
analysis.single_quoted_allowed = false;
|
||||
analysis.block_allowed = false;
|
||||
}
|
||||
if line_breaks {
|
||||
emitter.scalar_data.flow_plain_allowed = false;
|
||||
emitter.scalar_data.block_plain_allowed = false;
|
||||
analysis.flow_plain_allowed = false;
|
||||
analysis.block_plain_allowed = false;
|
||||
}
|
||||
if flow_indicators {
|
||||
emitter.scalar_data.flow_plain_allowed = false;
|
||||
analysis.flow_plain_allowed = false;
|
||||
}
|
||||
if block_indicators {
|
||||
emitter.scalar_data.block_plain_allowed = false;
|
||||
analysis.block_plain_allowed = false;
|
||||
}
|
||||
Ok(())
|
||||
Ok(analysis)
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_analyze_event(
|
||||
fn yaml_emitter_analyze_event<'a>(
|
||||
emitter: &mut yaml_emitter_t,
|
||||
event: &yaml_event_t,
|
||||
) -> Result<(), ()> {
|
||||
emitter.anchor_data.anchor = ptr::null_mut::<yaml_char_t>();
|
||||
emitter.anchor_data.anchor_length = 0_u64;
|
||||
emitter.tag_data.handle = ptr::null_mut::<yaml_char_t>();
|
||||
emitter.tag_data.handle_length = 0_u64;
|
||||
emitter.tag_data.suffix = ptr::null_mut::<yaml_char_t>();
|
||||
emitter.tag_data.suffix_length = 0_u64;
|
||||
emitter.scalar_data.value = ptr::null_mut::<yaml_char_t>();
|
||||
emitter.scalar_data.length = 0_u64;
|
||||
event: &'a yaml_event_t,
|
||||
tag_directives: &'a [yaml_tag_directive_t],
|
||||
) -> Result<Analysis<'a>, ()> {
|
||||
let mut analysis = Analysis::default();
|
||||
|
||||
match &event.data {
|
||||
YamlEventData::Alias { anchor } => yaml_emitter_analyze_anchor(emitter, anchor, true),
|
||||
YamlEventData::Alias { anchor } => {
|
||||
analysis.anchor = Some(yaml_emitter_analyze_anchor(emitter, anchor, true)?);
|
||||
}
|
||||
YamlEventData::Scalar {
|
||||
anchor,
|
||||
tag,
|
||||
|
@ -1189,12 +1244,16 @@ unsafe fn yaml_emitter_analyze_event(
|
|||
} => {
|
||||
let (plain_implicit, quoted_implicit) = (*plain_implicit, *quoted_implicit);
|
||||
if let Some(anchor) = anchor {
|
||||
yaml_emitter_analyze_anchor(emitter, anchor, false)?;
|
||||
analysis.anchor = Some(yaml_emitter_analyze_anchor(emitter, anchor, false)?);
|
||||
}
|
||||
if tag.is_some() && (emitter.canonical || !plain_implicit && !quoted_implicit) {
|
||||
yaml_emitter_analyze_tag(emitter, tag.as_deref().unwrap())?;
|
||||
analysis.tag = Some(yaml_emitter_analyze_tag(
|
||||
emitter,
|
||||
tag.as_deref().unwrap(),
|
||||
tag_directives,
|
||||
)?);
|
||||
}
|
||||
yaml_emitter_analyze_scalar(emitter, value)
|
||||
analysis.scalar = Some(yaml_emitter_analyze_scalar(emitter, value)?);
|
||||
}
|
||||
YamlEventData::SequenceStart {
|
||||
anchor,
|
||||
|
@ -1203,12 +1262,15 @@ unsafe fn yaml_emitter_analyze_event(
|
|||
..
|
||||
} => {
|
||||
if let Some(anchor) = anchor {
|
||||
yaml_emitter_analyze_anchor(emitter, anchor, false)?;
|
||||
analysis.anchor = Some(yaml_emitter_analyze_anchor(emitter, anchor, false)?);
|
||||
}
|
||||
if tag.is_some() && (emitter.canonical || !*implicit) {
|
||||
yaml_emitter_analyze_tag(emitter, tag.as_deref().unwrap())?;
|
||||
analysis.tag = Some(yaml_emitter_analyze_tag(
|
||||
emitter,
|
||||
tag.as_deref().unwrap(),
|
||||
tag_directives,
|
||||
)?);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
YamlEventData::MappingStart {
|
||||
anchor,
|
||||
|
@ -1217,15 +1279,20 @@ unsafe fn yaml_emitter_analyze_event(
|
|||
..
|
||||
} => {
|
||||
if let Some(anchor) = anchor {
|
||||
yaml_emitter_analyze_anchor(emitter, anchor, false)?;
|
||||
analysis.anchor = Some(yaml_emitter_analyze_anchor(emitter, anchor, false)?);
|
||||
}
|
||||
if tag.is_some() && (emitter.canonical || !*implicit) {
|
||||
yaml_emitter_analyze_tag(emitter, tag.as_deref().unwrap())?;
|
||||
analysis.tag = Some(yaml_emitter_analyze_tag(
|
||||
emitter,
|
||||
tag.as_deref().unwrap(),
|
||||
tag_directives,
|
||||
)?);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
_ => Ok(()),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(analysis)
|
||||
}
|
||||
|
||||
unsafe fn yaml_emitter_write_bom(emitter: &mut yaml_emitter_t) -> Result<(), ()> {
|
||||
|
|
|
@ -47,7 +47,7 @@ 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, u32 as c_uint, u64 as c_ulong, u8 as c_uchar,
|
||||
i32 as c_int, i64 as c_long, u32 as c_uint, u64 as c_ulong, u8 as c_uchar,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
89
src/yaml.rs
89
src/yaml.rs
|
@ -6,7 +6,7 @@ use crate::libc;
|
|||
use core::ptr;
|
||||
|
||||
pub use self::yaml_encoding_t::*;
|
||||
pub use core::primitive::{i64 as ptrdiff_t, u64 as size_t, u8 as yaml_char_t};
|
||||
pub use core::primitive::{i64 as ptrdiff_t, u64 as size_t};
|
||||
|
||||
/// The version directive data.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -936,12 +936,6 @@ pub struct yaml_emitter_t {
|
|||
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?
|
||||
|
@ -985,9 +979,6 @@ impl Default for yaml_emitter_t {
|
|||
whitespace: Default::default(),
|
||||
indention: Default::default(),
|
||||
open_ended: Default::default(),
|
||||
anchor_data: Default::default(),
|
||||
tag_data: Default::default(),
|
||||
scalar_data: Default::default(),
|
||||
opened: Default::default(),
|
||||
closed: Default::default(),
|
||||
anchors: Default::default(),
|
||||
|
@ -1015,81 +1006,3 @@ impl Default for unnamed_yaml_emitter_t_output_string {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub(crate) struct unnamed_yaml_emitter_t_anchor_data {
|
||||
/// The anchor value.
|
||||
pub anchor: *const yaml_char_t,
|
||||
/// The anchor length.
|
||||
pub anchor_length: size_t,
|
||||
/// Is it an alias?
|
||||
pub alias: bool,
|
||||
}
|
||||
|
||||
impl Default for unnamed_yaml_emitter_t_anchor_data {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
anchor: ptr::null_mut(),
|
||||
anchor_length: 0,
|
||||
alias: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub(crate) struct unnamed_yaml_emitter_t_tag_data {
|
||||
/// The tag handle.
|
||||
pub handle: *const yaml_char_t,
|
||||
/// The tag handle length.
|
||||
pub handle_length: size_t,
|
||||
/// The tag suffix.
|
||||
pub suffix: *const yaml_char_t,
|
||||
/// The tag suffix length.
|
||||
pub suffix_length: size_t,
|
||||
}
|
||||
|
||||
impl Default for unnamed_yaml_emitter_t_tag_data {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
handle: ptr::null_mut(),
|
||||
handle_length: 0,
|
||||
suffix: ptr::null_mut(),
|
||||
suffix_length: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub(crate) struct unnamed_yaml_emitter_t_scalar_data {
|
||||
/// The scalar value.
|
||||
pub value: *const 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,
|
||||
}
|
||||
|
||||
impl Default for unnamed_yaml_emitter_t_scalar_data {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
value: ptr::null_mut(),
|
||||
length: 0,
|
||||
multiline: false,
|
||||
flow_plain_allowed: false,
|
||||
block_plain_allowed: false,
|
||||
single_quoted_allowed: false,
|
||||
block_allowed: false,
|
||||
style: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue