Skip to content

Commit 2331259

Browse files
authored
Merge pull request #396 from dtolnay/trailingbackslash
Factor out logic for processing trailing backslashes
2 parents 07ffd04 + aebe7a0 commit 2331259

File tree

1 file changed

+35
-54
lines changed

1 file changed

+35
-54
lines changed

src/parse.rs

+35-54
Original file line numberDiff line numberDiff line change
@@ -371,8 +371,8 @@ fn string(input: Cursor) -> Result<Cursor, Reject> {
371371
}
372372
}
373373

374-
fn cooked_string(input: Cursor) -> Result<Cursor, Reject> {
375-
let mut chars = input.char_indices().peekable();
374+
fn cooked_string(mut input: Cursor) -> Result<Cursor, Reject> {
375+
let mut chars = input.char_indices();
376376

377377
while let Some((i, ch)) = chars.next() {
378378
match ch {
@@ -393,21 +393,10 @@ fn cooked_string(input: Cursor) -> Result<Cursor, Reject> {
393393
Some((_, 'u')) => {
394394
backslash_u(&mut chars)?;
395395
}
396-
Some((_, ch @ '\n')) | Some((_, ch @ '\r')) => {
397-
let mut last = ch;
398-
loop {
399-
if last == '\r' && chars.next().map_or(true, |(_, ch)| ch != '\n') {
400-
return Err(Reject);
401-
}
402-
match chars.peek() {
403-
Some((_, ch @ ' ')) | Some((_, ch @ '\t')) | Some((_, ch @ '\n'))
404-
| Some((_, ch @ '\r')) => {
405-
last = *ch;
406-
chars.next();
407-
}
408-
_ => break,
409-
}
410-
}
396+
Some((newline, ch @ '\n')) | Some((newline, ch @ '\r')) => {
397+
input = input.advance(newline + 1);
398+
trailing_backslash(&mut input, ch as u8)?;
399+
chars = input.char_indices();
411400
}
412401
_ => break,
413402
},
@@ -465,26 +454,9 @@ fn cooked_byte_string(mut input: Cursor) -> Result<Cursor, Reject> {
465454
Some((_, b'n')) | Some((_, b'r')) | Some((_, b't')) | Some((_, b'\\'))
466455
| Some((_, b'0')) | Some((_, b'\'')) | Some((_, b'"')) => {}
467456
Some((newline, b @ b'\n')) | Some((newline, b @ b'\r')) => {
468-
let mut last = b;
469-
let rest = input.advance(newline + 1);
470-
let mut whitespace = rest.bytes().enumerate();
471-
loop {
472-
if last == b'\r' && whitespace.next().map_or(true, |(_, b)| b != b'\n') {
473-
return Err(Reject);
474-
}
475-
match whitespace.next() {
476-
Some((_, b @ b' ')) | Some((_, b @ b'\t')) | Some((_, b @ b'\n'))
477-
| Some((_, b @ b'\r')) => {
478-
last = b;
479-
}
480-
Some((offset, _)) => {
481-
input = rest.advance(offset);
482-
bytes = input.bytes().enumerate();
483-
break;
484-
}
485-
None => return Err(Reject),
486-
}
487-
}
457+
input = input.advance(newline + 1);
458+
trailing_backslash(&mut input, b)?;
459+
bytes = input.bytes().enumerate();
488460
}
489461
_ => break,
490462
},
@@ -567,8 +539,8 @@ fn raw_c_string(input: Cursor) -> Result<Cursor, Reject> {
567539
Err(Reject)
568540
}
569541

570-
fn cooked_c_string(input: Cursor) -> Result<Cursor, Reject> {
571-
let mut chars = input.char_indices().peekable();
542+
fn cooked_c_string(mut input: Cursor) -> Result<Cursor, Reject> {
543+
let mut chars = input.char_indices();
572544

573545
while let Some((i, ch)) = chars.next() {
574546
match ch {
@@ -591,21 +563,10 @@ fn cooked_c_string(input: Cursor) -> Result<Cursor, Reject> {
591563
break;
592564
}
593565
}
594-
Some((_, ch @ '\n')) | Some((_, ch @ '\r')) => {
595-
let mut last = ch;
596-
loop {
597-
if last == '\r' && chars.next().map_or(true, |(_, ch)| ch != '\n') {
598-
return Err(Reject);
599-
}
600-
match chars.peek() {
601-
Some((_, ch @ ' ')) | Some((_, ch @ '\t')) | Some((_, ch @ '\n'))
602-
| Some((_, ch @ '\r')) => {
603-
last = *ch;
604-
chars.next();
605-
}
606-
_ => break,
607-
}
608-
}
566+
Some((newline, ch @ '\n')) | Some((newline, ch @ '\r')) => {
567+
input = input.advance(newline + 1);
568+
trailing_backslash(&mut input, ch as u8)?;
569+
chars = input.char_indices();
609570
}
610571
_ => break,
611572
},
@@ -730,6 +691,26 @@ where
730691
Err(Reject)
731692
}
732693

694+
fn trailing_backslash(input: &mut Cursor, mut last: u8) -> Result<(), Reject> {
695+
let mut whitespace = input.bytes().enumerate();
696+
loop {
697+
if last == b'\r' && whitespace.next().map_or(true, |(_, b)| b != b'\n') {
698+
return Err(Reject);
699+
}
700+
match whitespace.next() {
701+
Some((_, b @ b' ')) | Some((_, b @ b'\t')) | Some((_, b @ b'\n'))
702+
| Some((_, b @ b'\r')) => {
703+
last = b;
704+
}
705+
Some((offset, _)) => {
706+
*input = input.advance(offset);
707+
return Ok(());
708+
}
709+
None => return Err(Reject),
710+
}
711+
}
712+
}
713+
733714
fn float(input: Cursor) -> Result<Cursor, Reject> {
734715
let mut rest = float_digits(input)?;
735716
if let Some(ch) = rest.chars().next() {

0 commit comments

Comments
 (0)