Feature/scanner/option #27

Merged
bazaah merged 19 commits from feature/scanner/option into master 2021-09-09 19:29:29 +00:00
2 changed files with 30 additions and 17 deletions
Showing only changes of commit 89225e1481 - Show all commits

View File

@ -193,7 +193,7 @@ impl Scanner
[SINGLE, ..] | [DOUBLE, ..] => self.fetch_flow_scalar(opts, base, tokens), [SINGLE, ..] | [DOUBLE, ..] => self.fetch_flow_scalar(opts, base, tokens),
// Is it a plain scalar? // Is it a plain scalar?
_ if self.is_plain_scalar(*base) => self.fetch_plain_scalar(base, tokens), _ if self.is_plain_scalar(*base) => self.fetch_plain_scalar(opts, base, tokens),
// Otherwise its an error // Otherwise its an error
_ => return Err(ScanError::UnknownDelimiter), _ => return Err(ScanError::UnknownDelimiter),
@ -431,6 +431,7 @@ impl Scanner
fn fetch_plain_scalar<'de>( fn fetch_plain_scalar<'de>(
&mut self, &mut self,
opts: Flags,
base: &mut &'de str, base: &mut &'de str,
tokens: &mut Tokens<'de>, tokens: &mut Tokens<'de>,
) -> Result<()> ) -> Result<()>
@ -440,7 +441,7 @@ impl Scanner
self.save_key(!REQUIRED)?; self.save_key(!REQUIRED)?;
let (token, amt) = scan_plain_scalar(buffer, &mut stats, &self.context)?; let (token, amt) = scan_plain_scalar(opts, buffer, &mut stats, &self.context)?;
// A simple key cannot follow a plain scalar, there must be // A simple key cannot follow a plain scalar, there must be
// an indicator or new line before a key is valid // an indicator or new line before a key is valid

View File

@ -2,6 +2,7 @@ use crate::{
scanner::{ scanner::{
context::Context, context::Context,
error::{ScanError, ScanResult as Result}, error::{ScanError, ScanResult as Result},
flag::Flags,
stats::MStats, stats::MStats,
}, },
token::{ScalarStyle, Token}, token::{ScalarStyle, Token},
@ -17,6 +18,7 @@ use crate::{
/// YAML 1.2: Section 7.3.3 /// YAML 1.2: Section 7.3.3
/// yaml.org/spec/1.2/spec.html#ns-plain-first(c) /// yaml.org/spec/1.2/spec.html#ns-plain-first(c)
pub(in crate::scanner) fn scan_plain_scalar<'de>( pub(in crate::scanner) fn scan_plain_scalar<'de>(
opts: Flags,
base: &'de str, base: &'de str,
stats: &mut MStats, stats: &mut MStats,
cxt: &Context, cxt: &Context,
@ -53,6 +55,7 @@ pub(in crate::scanner) fn scan_plain_scalar<'de>(
// Inside flow contexts you *may not* start a plain scalar // Inside flow contexts you *may not* start a plain scalar
// with a ':', '?', or '-' followed by a flow indicator // with a ':', '?', or '-' followed by a flow indicator
cache!(~buffer, 2, opts)?;
if flow_context && check!(~buffer => b':' | b'?' | b'-') && flow_indicator(buffer, 1) if flow_context && check!(~buffer => b':' | b'?' | b'-') && flow_indicator(buffer, 1)
{ {
return Err(ScanError::InvalidPlainScalar); return Err(ScanError::InvalidPlainScalar);
@ -60,6 +63,10 @@ pub(in crate::scanner) fn scan_plain_scalar<'de>(
'scalar: loop 'scalar: loop
{ {
// 4 is the largest character sequence we can encounter
// (document indicators)
cache!(~buffer, 4, opts)?;
if buffer.is_empty() if buffer.is_empty()
{ {
break 'scalar; break 'scalar;
@ -110,6 +117,8 @@ pub(in crate::scanner) fn scan_plain_scalar<'de>(
// Handle non whitespace characters // Handle non whitespace characters
while !isWhiteSpaceZ!(~buffer) while !isWhiteSpaceZ!(~buffer)
{ {
cache!(~buffer, 2, opts)?;
if (check!(~buffer => b':') && isWhiteSpaceZ!(~buffer, 1)) if (check!(~buffer => b':') && isWhiteSpaceZ!(~buffer, 1))
|| flow_context && flow_indicator(buffer, 0) || flow_context && flow_indicator(buffer, 0)
{ {
@ -128,6 +137,8 @@ pub(in crate::scanner) fn scan_plain_scalar<'de>(
// Handle whitespace characters // Handle whitespace characters
loop loop
{ {
cache!(~buffer, 1, opts)?;
match (isBlank!(~buffer), isBreak!(~buffer)) match (isBlank!(~buffer), isBreak!(~buffer))
{ {
// No more whitespace, exit loop // No more whitespace, exit loop
@ -242,6 +253,7 @@ mod tests
use ScalarStyle::Plain; use ScalarStyle::Plain;
use super::*; use super::*;
use crate::scanner::flag::O_ZEROED;
type TestResult = anyhow::Result<()>; type TestResult = anyhow::Result<()>;
@ -280,7 +292,7 @@ mod tests
for (i, &data) in tests.iter().enumerate() for (i, &data) in tests.iter().enumerate()
{ {
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt) let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)
.map_err(|e| anyhow!("iteration {}: {}", i, e))?; .map_err(|e| anyhow!("iteration {}: {}", i, e))?;
assert_eq!(token, expected, "on iteration {}", i); assert_eq!(token, expected, "on iteration {}", i);
@ -301,7 +313,7 @@ mod tests
for (i, &data) in tests.iter().enumerate() for (i, &data) in tests.iter().enumerate()
{ {
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt) let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)
.map_err(|e| anyhow!("iteration {}: {}", i, e))?; .map_err(|e| anyhow!("iteration {}: {}", i, e))?;
assert_eq!(token, expected, "on iteration {}", i); assert_eq!(token, expected, "on iteration {}", i);
@ -320,7 +332,7 @@ mod tests
let cxt = cxt!(block -> [0]); let cxt = cxt!(block -> [0]);
let expected = Token::Scalar(cow!(""), Plain); let expected = Token::Scalar(cow!(""), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -339,7 +351,7 @@ mod tests
let cxt = cxt!(block -> [0]); let cxt = cxt!(block -> [0]);
let expected = Token::Scalar(cow!("hello"), Plain); let expected = Token::Scalar(cow!("hello"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -356,7 +368,7 @@ mod tests
let cxt = cxt!(block -> [0]); let cxt = cxt!(block -> [0]);
let expected = Token::Scalar(cow!("hello, world!"), Plain); let expected = Token::Scalar(cow!("hello, world!"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -379,7 +391,7 @@ mod tests
let cxt = cxt!(block -> [0]); let cxt = cxt!(block -> [0]);
let expected = Token::Scalar(cow!("hello this is a multi-line scalar"), Plain); let expected = Token::Scalar(cow!("hello this is a multi-line scalar"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -406,7 +418,7 @@ mod tests
let cxt = cxt!(block -> [0]); let cxt = cxt!(block -> [0]);
let expected = Token::Scalar(cow!("this is\n\na scalar\nwith line#breaks"), Plain); let expected = Token::Scalar(cow!("this is\n\na scalar\nwith line#breaks"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -423,7 +435,7 @@ mod tests
let cxt = cxt!(block -> [0]); let cxt = cxt!(block -> [0]);
let expected = Token::Scalar(cow!("hello"), Plain); let expected = Token::Scalar(cow!("hello"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -442,7 +454,7 @@ mod tests
let cxt = cxt!(flow -> 1); let cxt = cxt!(flow -> 1);
let expected = Token::Scalar(cow!("hello"), Plain); let expected = Token::Scalar(cow!("hello"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -461,7 +473,7 @@ mod tests
for (i, &data) in tests.iter().enumerate() for (i, &data) in tests.iter().enumerate()
{ {
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt) let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)
.map_err(|e| anyhow!("iteration {}: {}", i, e))?; .map_err(|e| anyhow!("iteration {}: {}", i, e))?;
assert_eq!(token, expected, "on iteration {}", i); assert_eq!(token, expected, "on iteration {}", i);
@ -485,7 +497,7 @@ string!";
let cxt = cxt!(flow -> 1); let cxt = cxt!(flow -> 1);
let expected = Token::Scalar(cow!("hello this is a multi-line string!"), Plain); let expected = Token::Scalar(cow!("hello this is a multi-line string!"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -514,7 +526,7 @@ breaks
let cxt = cxt!(flow -> 1); let cxt = cxt!(flow -> 1);
let expected = Token::Scalar(cow!("hello this\nbig\nstring\nhas\nline\nbreaks"), Plain); let expected = Token::Scalar(cow!("hello this\nbig\nstring\nhas\nline\nbreaks"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -531,7 +543,7 @@ breaks
let cxt = cxt!(flow -> 1); let cxt = cxt!(flow -> 1);
let expected = Token::Scalar(cow!("hello"), Plain); let expected = Token::Scalar(cow!("hello"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -548,7 +560,7 @@ breaks
let cxt = cxt!(flow -> 1); let cxt = cxt!(flow -> 1);
let expected = Token::Scalar(cow!("hello"), Plain); let expected = Token::Scalar(cow!("hello"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);
@ -569,7 +581,7 @@ breaks
let cxt = cxt!(flow -> 1); let cxt = cxt!(flow -> 1);
let expected = Token::Scalar(cow!("hello"), Plain); let expected = Token::Scalar(cow!("hello"), Plain);
let (token, amt) = scan_plain_scalar(data, &mut stats, &cxt)?; let (token, amt) = scan_plain_scalar(O_ZEROED, data, &mut stats, &cxt)?;
assert_eq!(token, expected); assert_eq!(token, expected);