annotate cmd/sievemgr/internal/config/scanner.go @ 22:fc5e6970a0d5 default tip

Add support for specifying an authorization identity on the command line
author Guido Berhoerster <guido+sievemgr@berhoerster.name>
date Wed, 17 Feb 2021 07:50:55 +0100
parents 4dff4c3f0fbb
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
1 // Copyright (C) 2020 Guido Berhoerster <guido+sievemgr@berhoerster.name>
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
2 //
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
3 // Permission is hereby granted, free of charge, to any person obtaining
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
4 // a copy of this software and associated documentation files (the
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
5 // "Software"), to deal in the Software without restriction, including
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
6 // without limitation the rights to use, copy, modify, merge, publish,
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
7 // distribute, sublicense, and/or sell copies of the Software, and to
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
8 // permit persons to whom the Software is furnished to do so, subject to
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
9 // the following conditions:
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
10 //
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
11 // The above copyright notice and this permission notice shall be included
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
12 // in all copies or substantial portions of the Software.
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
13 //
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
17 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
18 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
19 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
20 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
21
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
22 package config
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
23
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
24 import (
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
25 "bufio"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
26 "fmt"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
27 "io"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
28 "strings"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
29 "unicode"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
30 )
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
31
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
32 type token int
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
33
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
34 const (
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
35 tokenEOF token = -(iota + 1)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
36 tokenIllegal
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
37 tokenIdent
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
38 tokenNumber
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
39 tokenString
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
40 )
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
41
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
42 func (tok token) String() string {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
43 switch tok {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
44 case tokenIllegal:
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
45 return "illegal"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
46 case tokenEOF:
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
47 return "EOF"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
48 case tokenIdent:
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
49 return "identifier"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
50 case tokenNumber:
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
51 return "number"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
52 case tokenString:
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
53 return "string"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
54 default:
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
55 return "unknown"
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
56 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
57 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
58
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
59 func isWhitespaceRune(r rune) bool {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
60 return r == ' ' || r == '\t' || r == '\r' || r == '\n'
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
61 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
62
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
63 func isIdentRune(r rune) bool {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
64 return r >= 'A' && r <= 'Z' || r >= 'a' && r <= 'z'
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
65 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
66
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
67 func isNumberRune(r rune) bool {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
68 return r >= '0' && r <= '9'
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
69 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
70
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
71 type scanner struct {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
72 br *bufio.Reader
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
73 line int // line number for error messages
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
74 r rune // last read rune
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
75 rdSize int // last read size
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
76 rdOffset int // offset from beginning of file
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
77 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
78
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
79 func newScanner(br *bufio.Reader) *scanner {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
80 return &scanner{line: 1, br: br}
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
81 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
82
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
83 func (s *scanner) read() error {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
84 var size int
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
85 again:
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
86 r, size, err := s.br.ReadRune()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
87 if err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
88 return err
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
89 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
90
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
91 // skip over BOM at the beginning of the file
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
92 if r == bom && s.rdOffset == 0 {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
93 s.rdOffset += size
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
94 goto again
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
95 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
96
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
97 if s.r == '\n' {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
98 s.line++
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
99 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
100
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
101 s.r = r
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
102 s.rdOffset += size
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
103 s.rdSize = size
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
104
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
105 if r == unicode.ReplacementChar && size == 1 {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
106 return fmt.Errorf("illegal UTF-8 sequence")
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
107 } else if r == 0 {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
108 return fmt.Errorf("illegal nul byte")
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
109 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
110 return nil
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
111 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
112
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
113 func (s *scanner) unread() {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
114 if s.br.UnreadRune() != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
115 return
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
116 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
117
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
118 if b, _ := s.br.Peek(1); b[0] == '\n' {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
119 // moved back to the previous line
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
120 s.line--
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
121 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
122
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
123 s.r = 0
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
124 s.rdOffset -= s.rdSize
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
125 s.rdSize = 0
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
126 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
127
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
128 func (s *scanner) skipWhitespace() error {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
129 for {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
130 if err := s.read(); err == io.EOF {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
131 break
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
132 } else if err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
133 return err
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
134 } else if !isWhitespaceRune(s.r) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
135 s.unread()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
136 break
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
137 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
138 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
139 return nil
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
140 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
141
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
142 func (s *scanner) scanIdent() (token, string, error) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
143 var sb strings.Builder
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
144 for {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
145 if err := s.read(); err == io.EOF {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
146 break
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
147 } else if err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
148 return tokenIllegal, "", err
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
149 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
150 if isIdentRune(s.r) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
151 sb.WriteRune(s.r)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
152 } else if isWhitespaceRune(s.r) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
153 s.unread()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
154 break
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
155 } else {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
156 return tokenIllegal, "", fmt.Errorf("illegal rune in identifier: %q", s.r)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
157 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
158 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
159 if sb.Len() == 0 {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
160 return tokenIllegal, "", fmt.Errorf("expected identifier, got %q", s.r)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
161 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
162 return tokenIdent, sb.String(), nil
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
163 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
164
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
165 func (s *scanner) scanNumber() (token, string, error) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
166 var sb strings.Builder
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
167 for {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
168 if err := s.read(); err == io.EOF {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
169 break
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
170 } else if err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
171 return tokenIllegal, "", err
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
172 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
173 if isNumberRune(s.r) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
174 sb.WriteRune(s.r)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
175 } else if isWhitespaceRune(s.r) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
176 s.unread()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
177 break
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
178 } else {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
179 return tokenIllegal, "", fmt.Errorf("illegal rune in number: %q", s.r)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
180 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
181 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
182 if sb.Len() == 0 {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
183 return tokenIllegal, "", fmt.Errorf("expected number, got %q", s.r)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
184 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
185 return tokenNumber, sb.String(), nil
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
186 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
187
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
188 func (s *scanner) scanString() (token, string, error) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
189 if err := s.read(); err == io.EOF {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
190 return tokenIllegal, "", fmt.Errorf("unexpected EOF")
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
191 } else if err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
192 return tokenIllegal, "", err
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
193 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
194
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
195 if s.r != '"' {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
196 return tokenIllegal, "",
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
197 fmt.Errorf("expected '\"', got %q", s.r)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
198 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
199
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
200 var sb strings.Builder
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
201 var inEscape bool
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
202 for {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
203 if err := s.read(); err == io.EOF {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
204 return tokenIllegal, "", fmt.Errorf("unterminated string")
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
205 } else if err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
206 return tokenIllegal, "", err
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
207 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
208
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
209 if s.r == '\\' && !inEscape {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
210 inEscape = true
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
211 } else if s.r == '"' && !inEscape {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
212 break
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
213 } else {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
214 sb.WriteRune(s.r)
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
215 inEscape = false
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
216 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
217 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
218
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
219 return tokenString, sb.String(), nil
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
220 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
221
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
222 func (s *scanner) scan() (token, string, error) {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
223 if err := s.skipWhitespace(); err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
224 return tokenIllegal, "", err
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
225 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
226
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
227 if err := s.read(); err == io.EOF {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
228 return tokenEOF, "", nil
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
229 } else if err != nil {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
230 return tokenIllegal, "", err
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
231 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
232 r := s.r
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
233 s.unread()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
234
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
235 switch {
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
236 case isIdentRune(r):
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
237 return s.scanIdent()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
238 case isNumberRune(r):
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
239 return s.scanNumber()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
240 case r == '"':
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
241 return s.scanString()
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
242 }
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
243 return tokenIllegal, string(r), nil
4dff4c3f0fbb Introduce configuration file where account information is specified
Guido Berhoerster <guido+sievemgr@berhoerster.name>
parents:
diff changeset
244 }