diff --git a/src/scanner/mod.rs b/src/scanner/mod.rs index 0a41fbe..4658ebb 100644 --- a/src/scanner/mod.rs +++ b/src/scanner/mod.rs @@ -193,7 +193,7 @@ impl Scanner [SINGLE, ..] | [DOUBLE, ..] => self.fetch_flow_scalar(opts, base, tokens), // 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 _ => return Err(ScanError::UnknownDelimiter), @@ -431,6 +431,7 @@ impl Scanner fn fetch_plain_scalar<'de>( &mut self, + opts: Flags, base: &mut &'de str, tokens: &mut Tokens<'de>, ) -> Result<()> @@ -440,7 +441,7 @@ impl Scanner 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 // an indicator or new line before a key is valid diff --git a/src/scanner/scalar/plain.rs b/src/scanner/scalar/plain.rs index 22a63d6..6bbf646 100644 --- a/src/scanner/scalar/plain.rs +++ b/src/scanner/scalar/plain.rs @@ -2,6 +2,7 @@ use crate::{ scanner::{ context::Context, error::{ScanError, ScanResult as Result}, + flag::Flags, stats::MStats, }, token::{ScalarStyle, Token}, @@ -17,6 +18,7 @@ use crate::{ /// YAML 1.2: Section 7.3.3 /// yaml.org/spec/1.2/spec.html#ns-plain-first(c) pub(in crate::scanner) fn scan_plain_scalar<'de>( + opts: Flags, base: &'de str, stats: &mut MStats, 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 // with a ':', '?', or '-' followed by a flow indicator + cache!(~buffer, 2, opts)?; if flow_context && check!(~buffer => b':' | b'?' | b'-') && flow_indicator(buffer, 1) { return Err(ScanError::InvalidPlainScalar); @@ -60,6 +63,10 @@ pub(in crate::scanner) fn scan_plain_scalar<'de>( 'scalar: loop { + // 4 is the largest character sequence we can encounter + // (document indicators) + cache!(~buffer, 4, opts)?; + if buffer.is_empty() { break 'scalar; @@ -110,6 +117,8 @@ pub(in crate::scanner) fn scan_plain_scalar<'de>( // Handle non whitespace characters while !isWhiteSpaceZ!(~buffer) { + cache!(~buffer, 2, opts)?; + if (check!(~buffer => b':') && isWhiteSpaceZ!(~buffer, 1)) || flow_context && flow_indicator(buffer, 0) { @@ -128,6 +137,8 @@ pub(in crate::scanner) fn scan_plain_scalar<'de>( // Handle whitespace characters loop { + cache!(~buffer, 1, opts)?; + match (isBlank!(~buffer), isBreak!(~buffer)) { // No more whitespace, exit loop @@ -242,6 +253,7 @@ mod tests use ScalarStyle::Plain; use super::*; + use crate::scanner::flag::O_ZEROED; type TestResult = anyhow::Result<()>; @@ -280,7 +292,7 @@ mod tests 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))?; assert_eq!(token, expected, "on iteration {}", i); @@ -301,7 +313,7 @@ mod tests 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))?; assert_eq!(token, expected, "on iteration {}", i); @@ -320,7 +332,7 @@ mod tests let cxt = cxt!(block -> [0]); 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); @@ -339,7 +351,7 @@ mod tests let cxt = cxt!(block -> [0]); 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); @@ -356,7 +368,7 @@ mod tests let cxt = cxt!(block -> [0]); 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); @@ -379,7 +391,7 @@ mod tests let cxt = cxt!(block -> [0]); 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); @@ -406,7 +418,7 @@ mod tests let cxt = cxt!(block -> [0]); 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); @@ -423,7 +435,7 @@ mod tests let cxt = cxt!(block -> [0]); 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); @@ -442,7 +454,7 @@ mod tests let cxt = cxt!(flow -> 1); 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); @@ -461,7 +473,7 @@ mod tests 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))?; assert_eq!(token, expected, "on iteration {}", i); @@ -485,7 +497,7 @@ string!"; let cxt = cxt!(flow -> 1); 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); @@ -514,7 +526,7 @@ breaks let cxt = cxt!(flow -> 1); 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); @@ -531,7 +543,7 @@ breaks let cxt = cxt!(flow -> 1); 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); @@ -548,7 +560,7 @@ breaks let cxt = cxt!(flow -> 1); 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); @@ -569,7 +581,7 @@ breaks let cxt = cxt!(flow -> 1); 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);