@@ -17,24 +17,37 @@ pub enum EscapedChar {
1717 End ,
1818}
1919
20- #[ repr( u8 ) ]
20+ #[ derive( Clone , Copy , Default ) ]
21+ pub enum OctalParsing {
22+ #[ default]
23+ TwoDigits = 2 ,
24+ ThreeDigits = 3 ,
25+ }
26+
2127#[ derive( Clone , Copy ) ]
2228enum Base {
23- Oct = 8 ,
24- Hex = 16 ,
29+ Oct ( OctalParsing ) ,
30+ Hex ,
2531}
2632
2733impl Base {
34+ fn as_base ( & self ) -> u8 {
35+ match self {
36+ Base :: Oct ( _) => 8 ,
37+ Base :: Hex => 16 ,
38+ }
39+ }
40+
2841 fn max_digits ( & self ) -> u8 {
2942 match self {
30- Self :: Oct => 3 ,
43+ Self :: Oct ( parsing ) => * parsing as u8 ,
3144 Self :: Hex => 2 ,
3245 }
3346 }
3447
3548 fn convert_digit ( & self , c : u8 ) -> Option < u8 > {
3649 match self {
37- Self :: Oct => {
50+ Self :: Oct ( _ ) => {
3851 if matches ! ( c, b'0' ..=b'7' ) {
3952 Some ( c - b'0' )
4053 } else {
@@ -68,7 +81,7 @@ fn parse_code(input: &mut &[u8], base: Base) -> Option<u8> {
6881 let Some ( n) = base. convert_digit ( * c) else {
6982 break ;
7083 } ;
71- ret = ret. wrapping_mul ( base as u8 ) . wrapping_add ( n) ;
84+ ret = ret. wrapping_mul ( base. as_base ( ) ) . wrapping_add ( n) ;
7285 * input = rest;
7386 }
7487
@@ -87,7 +100,9 @@ fn parse_unicode(input: &mut &[u8], digits: u8) -> Option<char> {
87100 for _ in 1 ..digits {
88101 let ( c, rest) = input. split_first ( ) ?;
89102 let n = Base :: Hex . convert_digit ( * c) ?;
90- ret = ret. wrapping_mul ( Base :: Hex as u32 ) . wrapping_add ( n as u32 ) ;
103+ ret = ret
104+ . wrapping_mul ( Base :: Hex . as_base ( ) as u32 )
105+ . wrapping_add ( n as u32 ) ;
91106 * input = rest;
92107 }
93108
@@ -99,13 +114,16 @@ fn parse_unicode(input: &mut &[u8], digits: u8) -> Option<char> {
99114pub struct EscapeError { }
100115
101116/// Parse an escape sequence, like `\n` or `\xff`, etc.
102- pub fn parse_escape_code ( rest : & mut & [ u8 ] ) -> Result < EscapedChar , EscapeError > {
117+ pub fn parse_escape_code (
118+ rest : & mut & [ u8 ] ,
119+ zero_octal_parsing : OctalParsing ,
120+ ) -> Result < EscapedChar , EscapeError > {
103121 if let [ c, new_rest @ ..] = rest {
104122 // This is for the \NNN syntax for octal sequences.
105123 // Note that '0' is intentionally omitted because that
106124 // would be the \0NNN syntax.
107125 if let b'1' ..=b'7' = c {
108- if let Some ( parsed) = parse_code ( rest, Base :: Oct ) {
126+ if let Some ( parsed) = parse_code ( rest, Base :: Oct ( OctalParsing :: ThreeDigits ) ) {
109127 return Ok ( EscapedChar :: Byte ( parsed) ) ;
110128 }
111129 }
@@ -131,7 +149,7 @@ pub fn parse_escape_code(rest: &mut &[u8]) -> Result<EscapedChar, EscapeError> {
131149 }
132150 }
133151 b'0' => Ok ( EscapedChar :: Byte (
134- parse_code ( rest, Base :: Oct ) . unwrap_or ( b'\0' ) ,
152+ parse_code ( rest, Base :: Oct ( zero_octal_parsing ) ) . unwrap_or ( b'\0' ) ,
135153 ) ) ,
136154 b'u' => Ok ( EscapedChar :: Char ( parse_unicode ( rest, 4 ) . unwrap_or ( '\0' ) ) ) ,
137155 b'U' => Ok ( EscapedChar :: Char ( parse_unicode ( rest, 8 ) . unwrap_or ( '\0' ) ) ) ,
0 commit comments