()
| 563 | } |
| 564 | |
| 565 | func (p *textParser) advance() { |
| 566 | // Skip whitespace |
| 567 | p.skipWhitespace() |
| 568 | if p.done { |
| 569 | return |
| 570 | } |
| 571 | |
| 572 | // Start of non-whitespace |
| 573 | p.cur.err = nil |
| 574 | p.cur.offset, p.cur.line = p.offset, p.line |
| 575 | p.cur.unquoted = "" |
| 576 | switch p.s[0] { |
| 577 | case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': |
| 578 | // Single symbol |
| 579 | p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] |
| 580 | case '"', '\'': |
| 581 | // Quoted string |
| 582 | i := 1 |
| 583 | for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { |
| 584 | if p.s[i] == '\\' && i+1 < len(p.s) { |
| 585 | // skip escaped char |
| 586 | i++ |
| 587 | } |
| 588 | i++ |
| 589 | } |
| 590 | if i >= len(p.s) || p.s[i] != p.s[0] { |
| 591 | p.errorf("unmatched quote") |
| 592 | return |
| 593 | } |
| 594 | unq, err := unquoteC(p.s[1:i], rune(p.s[0])) |
| 595 | if err != nil { |
| 596 | p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) |
| 597 | return |
| 598 | } |
| 599 | p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] |
| 600 | p.cur.unquoted = unq |
| 601 | default: |
| 602 | i := 0 |
| 603 | for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { |
| 604 | i++ |
| 605 | } |
| 606 | if i == 0 { |
| 607 | p.errorf("unexpected byte %#x", p.s[0]) |
| 608 | return |
| 609 | } |
| 610 | p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] |
| 611 | } |
| 612 | p.offset += len(p.cur.value) |
| 613 | } |
| 614 | |
| 615 | // Back off the parser by one token. Can only be done between calls to next(). |
| 616 | // It makes the next advance() a no-op. |
no test coverage detected