25
25
mode Mode // sub-mode of the scanner
26
26
}
27
27
28
+ // State is a read-only copy of the scanner's internal state.
29
+ // See also `Scanner.state()`.
30
+ pub struct State {
31
+ pub :
32
+ col int // current column number (x coordinate)
33
+ line_nr int = 1 // current line number (y coordinate)
34
+ pos int // current flat/index position in the `text` field
35
+ mode Mode // sub-mode of the scanner
36
+ }
37
+
28
38
enum Mode {
29
39
normal
30
40
inside_string
@@ -426,6 +436,8 @@ fn (mut s Scanner) extract_multiline_string() ?string {
426
436
}
427
437
428
438
c := s.at ()
439
+ util.printdbg (@MOD + '.' + @STRUCT + '.' + @FN, 'c: `$c.ascii_str ()` / $c (quote type: $quote /$quote.ascii_str ())' )
440
+
429
441
if c == `\n ` {
430
442
s.inc_line_number ()
431
443
lit + = c.ascii_str ()
@@ -443,8 +455,6 @@ fn (mut s Scanner) extract_multiline_string() ?string {
443
455
}
444
456
}
445
457
446
- util.printdbg (@MOD + '.' + @STRUCT + '.' + @FN, 'c: `$c.ascii_str ()` / $c ' )
447
-
448
458
if c == quote {
449
459
if s.peek (1 ) == quote && s.peek (2 ) == quote {
450
460
if s.peek (3 ) == - 1 {
@@ -469,14 +479,16 @@ fn (mut s Scanner) extract_multiline_string() ?string {
469
479
return lit
470
480
}
471
481
472
- // handle_escapes
482
+ // handle_escapes returns any escape character sequence.
483
+ // For escape sequence validation see `Checker.check_quoted_escapes`.
473
484
fn (mut s Scanner) handle_escapes (quote byte , is_multiline bool ) (string , int ) {
474
485
c := s.at ()
475
486
mut lit := c.ascii_str ()
476
- if s.peek (1 ) == byte (92 ) {
477
- lit + = lit
478
- util.printdbg (@MOD + '.' + @STRUCT + '.' + @FN, 'gulp escaped `$lit `' )
479
- return lit, 1
487
+ if s.peek (1 ) == `u` && byte (s.peek (2 )).is_hex_digit () && byte (s.peek (3 )).is_hex_digit ()
488
+ && byte (s.peek (4 )).is_hex_digit () && byte (s.peek (5 )).is_hex_digit () {
489
+ lit + = s.text[s.pos + 1 ..s.pos + 6 ] // .ascii_str()
490
+ util.printdbg (@MOD + '.' + @STRUCT + '.' + @FN, 'gulp escaped unicode `$lit `' )
491
+ return lit, 4
480
492
} else if s.peek (1 ) == quote {
481
493
if (! is_multiline && s.peek (2 ) == `\n ` )
482
494
|| (is_multiline && s.peek (2 ) == quote && s.peek (3 ) == quote && s.peek (4 ) == `\n ` ) {
@@ -486,13 +498,9 @@ fn (mut s Scanner) handle_escapes(quote byte, is_multiline bool) (string, int) {
486
498
lit + = quote.ascii_str ()
487
499
util.printdbg (@MOD + '.' + @STRUCT + '.' + @FN, 'gulp escaped `$lit `' )
488
500
return lit, 1
489
- } else if s.peek (1 ) == `u` && byte (s.peek (2 )).is_hex_digit () && byte (s.peek (3 )).is_hex_digit ()
490
- && byte (s.peek (4 )).is_hex_digit () && byte (s.peek (5 )).is_hex_digit () {
491
- lit + = s.text[s.pos + 1 ..s.pos + 6 ] // .ascii_str()
492
- util.printdbg (@MOD + '.' + @STRUCT + '.' + @FN, 'gulp escaped `$lit `' )
493
- return lit, 4
494
501
}
495
- return '' , 0
502
+ lit + = byte (s.peek (1 )).ascii_str ()
503
+ return lit, 1
496
504
}
497
505
498
506
// extract_number collects and returns a string containing
@@ -542,3 +550,13 @@ pub fn (s Scanner) excerpt(pos int, margin int) string {
542
550
end := if pos + margin < s.text.len { pos + margin } else { s.text.len }
543
551
return s.text[start..end].replace ('\n ' , r '\n' )
544
552
}
553
+
554
+ // state returns a read-only view of the scanner's internal state.
555
+ pub fn (s Scanner) state () State {
556
+ return State{
557
+ col: s.col
558
+ line_nr: s.line_nr
559
+ pos: s.pos
560
+ mode: s.mode
561
+ }
562
+ }
0 commit comments