History

Clarify value_impl index handling

This clarifies that in the parsing loop, we are dealing with the current index. This also makes it so we have a more consistent pattern for updating the current index. This isn't interesting on its own but is prep for unrolling some of the state

Ed Page committed 3 years ago

Commit b7909481 parent 5fc10961 file · +13 −14Browse files

Unified · Split

gix-config/src/parse/nom/mod.rs+13−14
@@ -257,7 +257,7 @@ fn config_value<'i>(i: &'i [u8], dispatch: &mut impl FnMut(Event<'i>)) -> IResul · 256 unmodified lines
257/// line values as well as values that are continuations.257/// line values as well as values that are continuations.
258fn value_impl<'i>(i: &'i [u8], dispatch: &mut impl FnMut(Event<'i>)) -> IResult<&'i [u8], usize> {258fn value_impl<'i>(i: &'i [u8], dispatch: &mut impl FnMut(Event<'i>)) -> IResult<&'i [u8], usize> {
259 let new_err = |kind| winnow::error::ErrMode::from_error_kind(i, kind);259 let new_err = |kind| winnow::error::ErrMode::from_error_kind(i, kind);
260 let mut value_end = None::<usize>;260 let mut value_end = None;
261 let mut value_start: usize = 0;261 let mut value_start: usize = 0;
262 let mut newlines = 0;262 let mut newlines = 0;
263 263
@@ -266,14 +266,17 @@ fn value_impl<'i>(i: &'i [u8], dispatch: &mut impl FnMut(Event<'i>)) -> IResult< · 2 unmodified lines
266 let mut is_in_quotes = false;266 let mut is_in_quotes = false;
267 // Used to determine if we return a Value or Value{Not,}Done267 // Used to determine if we return a Value or Value{Not,}Done
268 let mut partial_value_found = false;268 let mut partial_value_found = false;
269 let mut last_value_index: usize = 0;269 let mut current_index: usize = 0;
270 270
271 let mut bytes = i.iter();271 let mut bytes = i.iter();
272 while let Some(mut c) = bytes.next() {272 while let Some(mut c) = bytes.next() {
273 if prev_char_was_backslash {273 if prev_char_was_backslash {
274 prev_char_was_backslash = false;274 prev_char_was_backslash = false;
275 let escape_index = current_index - 1;
276 let escaped_index = current_index;
275 let mut consumed = 1;277 let mut consumed = 1;
276 if *c == b'\r' {278 if *c == b'\r' {
279 current_index += 1;
277 c = bytes.next().ok_or_else(|| new_err(ErrorKind::Token))?;280 c = bytes.next().ok_or_else(|| new_err(ErrorKind::Token))?;
278 if *c != b'\n' {281 if *c != b'\n' {
279 return Err(new_err(ErrorKind::Slice));282 return Err(new_err(ErrorKind::Slice));
@@ -284,21 +287,16 @@ fn value_impl<'i>(i: &'i [u8], dispatch: &mut impl FnMut(Event<'i>)) -> IResult< · 4 unmodified lines
284 match c {287 match c {
285 b'\n' => {288 b'\n' => {
286 partial_value_found = true;289 partial_value_found = true;
287 let backslash = 1;
288 dispatch(Event::ValueNotDone(Cow::Borrowed(290 dispatch(Event::ValueNotDone(Cow::Borrowed(
289 i[value_start..last_value_index - backslash].as_bstr(),291 i[value_start..escape_index].as_bstr(),
290 )));292 )));
291 let nl_end = last_value_index + consumed;293 let nl_end = escaped_index + consumed;
292 dispatch(Event::Newline(Cow::Borrowed(i[last_value_index..nl_end].as_bstr())));294 dispatch(Event::Newline(Cow::Borrowed(i[escaped_index..nl_end].as_bstr())));
293 value_start = nl_end;295 value_start = nl_end;
294 value_end = None;296 value_end = None;
295 newlines += 1;297 newlines += 1;
296
297 last_value_index += consumed;
298 }
299 b'n' | b't' | b'\\' | b'b' | b'"' => {
300 last_value_index += 1;
301 }298 }
299 b'n' | b't' | b'\\' | b'b' | b'"' => {}
302 _ => {300 _ => {
303 return Err(new_err(ErrorKind::Token));301 return Err(new_err(ErrorKind::Token));
304 }302 }
@@ -306,19 +304,19 @@ fn value_impl<'i>(i: &'i [u8], dispatch: &mut impl FnMut(Event<'i>)) -> IResult< · 1 unmodified line
306 } else {304 } else {
307 match c {305 match c {
308 b'\n' => {306 b'\n' => {
309 value_end = last_value_index.into();307 value_end = Some(current_index);
310 break;308 break;
311 }309 }
312 b';' | b'#' if !is_in_quotes => {310 b';' | b'#' if !is_in_quotes => {
313 value_end = last_value_index.into();311 value_end = Some(current_index);
314 break;312 break;
315 }313 }
316 b'\\' => prev_char_was_backslash = true,314 b'\\' => prev_char_was_backslash = true,
317 b'"' => is_in_quotes = !is_in_quotes,315 b'"' => is_in_quotes = !is_in_quotes,
318 _ => {}316 _ => {}
319 }317 }
320 last_value_index += 1;
321 }318 }
319 current_index += 1;
322 }320 }
323 if prev_char_was_backslash {321 if prev_char_was_backslash {
324 return Err(new_err(ErrorKind::Token));322 return Err(new_err(ErrorKind::Token));
@@ -326,6 +324,7 @@ fn value_impl<'i>(i: &'i [u8], dispatch: &mut impl FnMut(Event<'i>)) -> IResult< · 1 unmodified line
326 if is_in_quotes {324 if is_in_quotes {
327 return Err(new_err(ErrorKind::Slice));325 return Err(new_err(ErrorKind::Slice));
328 }326 }
327 let last_value_index = current_index;
329 328
330 let value_end = match value_end {329 let value_end = match value_end {
331 None => {330 None => {