annotate vendor/github.com/dlclark/regexp2/syntax/prefix.go @ 66:787b5ee0289d draft

Use vendored modules Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author yakumo.izuru
date Sun, 23 Jul 2023 13:18:53 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
66
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1 package syntax
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
3 import (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
4 "bytes"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
5 "fmt"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
6 "strconv"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
7 "unicode"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
8 "unicode/utf8"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
9 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
10
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
11 type Prefix struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
12 PrefixStr []rune
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
13 PrefixSet CharSet
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
14 CaseInsensitive bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
15 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
16
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
17 // It takes a RegexTree and computes the set of chars that can start it.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
18 func getFirstCharsPrefix(tree *RegexTree) *Prefix {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
19 s := regexFcd{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
20 fcStack: make([]regexFc, 32),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
21 intStack: make([]int, 32),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
22 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
23 fc := s.regexFCFromRegexTree(tree)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
24
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
25 if fc == nil || fc.nullable || fc.cc.IsEmpty() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
26 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
27 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
28 fcSet := fc.getFirstChars()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
29 return &Prefix{PrefixSet: fcSet, CaseInsensitive: fc.caseInsensitive}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
30 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
31
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
32 type regexFcd struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
33 intStack []int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
34 intDepth int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
35 fcStack []regexFc
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
36 fcDepth int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
37 skipAllChildren bool // don't process any more children at the current level
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
38 skipchild bool // don't process the current child.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
39 failed bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
40 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
41
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
42 /*
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
43 * The main FC computation. It does a shortcutted depth-first walk
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
44 * through the tree and calls CalculateFC to emits code before
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
45 * and after each child of an interior node, and at each leaf.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
46 */
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
47 func (s *regexFcd) regexFCFromRegexTree(tree *RegexTree) *regexFc {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
48 curNode := tree.root
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
49 curChild := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
50
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
51 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
52 if len(curNode.children) == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
53 // This is a leaf node
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
54 s.calculateFC(curNode.t, curNode, 0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
55 } else if curChild < len(curNode.children) && !s.skipAllChildren {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
56 // This is an interior node, and we have more children to analyze
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
57 s.calculateFC(curNode.t|beforeChild, curNode, curChild)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
58
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
59 if !s.skipchild {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
60 curNode = curNode.children[curChild]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
61 // this stack is how we get a depth first walk of the tree.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
62 s.pushInt(curChild)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
63 curChild = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
64 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
65 curChild++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
66 s.skipchild = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
67 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
68 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
69 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
70
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
71 // This is an interior node where we've finished analyzing all the children, or
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
72 // the end of a leaf node.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
73 s.skipAllChildren = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
74
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
75 if s.intIsEmpty() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
76 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
77 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
78
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
79 curChild = s.popInt()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
80 curNode = curNode.next
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
81
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
82 s.calculateFC(curNode.t|afterChild, curNode, curChild)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
83 if s.failed {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
84 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
85 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
86
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
87 curChild++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
88 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
89
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
90 if s.fcIsEmpty() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
91 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
92 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
93
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
94 return s.popFC()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
95 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
96
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
97 // To avoid recursion, we use a simple integer stack.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
98 // This is the push.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
99 func (s *regexFcd) pushInt(I int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
100 if s.intDepth >= len(s.intStack) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
101 expanded := make([]int, s.intDepth*2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
102 copy(expanded, s.intStack)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
103 s.intStack = expanded
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
104 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
105
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
106 s.intStack[s.intDepth] = I
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
107 s.intDepth++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
108 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
109
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
110 // True if the stack is empty.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
111 func (s *regexFcd) intIsEmpty() bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
112 return s.intDepth == 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
113 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
114
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
115 // This is the pop.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
116 func (s *regexFcd) popInt() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
117 s.intDepth--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
118 return s.intStack[s.intDepth]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
119 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
120
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
121 // We also use a stack of RegexFC objects.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
122 // This is the push.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
123 func (s *regexFcd) pushFC(fc regexFc) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
124 if s.fcDepth >= len(s.fcStack) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
125 expanded := make([]regexFc, s.fcDepth*2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
126 copy(expanded, s.fcStack)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
127 s.fcStack = expanded
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
128 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
129
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
130 s.fcStack[s.fcDepth] = fc
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
131 s.fcDepth++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
132 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
133
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
134 // True if the stack is empty.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
135 func (s *regexFcd) fcIsEmpty() bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
136 return s.fcDepth == 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
137 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
138
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
139 // This is the pop.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
140 func (s *regexFcd) popFC() *regexFc {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
141 s.fcDepth--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
142 return &s.fcStack[s.fcDepth]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
143 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
144
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
145 // This is the top.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
146 func (s *regexFcd) topFC() *regexFc {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
147 return &s.fcStack[s.fcDepth-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
148 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
149
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
150 // Called in Beforechild to prevent further processing of the current child
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
151 func (s *regexFcd) skipChild() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
152 s.skipchild = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
153 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
154
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
155 // FC computation and shortcut cases for each node type
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
156 func (s *regexFcd) calculateFC(nt nodeType, node *regexNode, CurIndex int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
157 //fmt.Printf("NodeType: %v, CurIndex: %v, Desc: %v\n", nt, CurIndex, node.description())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
158 ci := false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
159 rtl := false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
160
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
161 if nt <= ntRef {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
162 if (node.options & IgnoreCase) != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
163 ci = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
164 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
165 if (node.options & RightToLeft) != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
166 rtl = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
167 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
168 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
169
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
170 switch nt {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
171 case ntConcatenate | beforeChild, ntAlternate | beforeChild, ntTestref | beforeChild, ntLoop | beforeChild, ntLazyloop | beforeChild:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
172 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
173
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
174 case ntTestgroup | beforeChild:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
175 if CurIndex == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
176 s.skipChild()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
177 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
178 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
179
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
180 case ntEmpty:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
181 s.pushFC(regexFc{nullable: true})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
182 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
183
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
184 case ntConcatenate | afterChild:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
185 if CurIndex != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
186 child := s.popFC()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
187 cumul := s.topFC()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
188
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
189 s.failed = !cumul.addFC(*child, true)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
190 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
191
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
192 fc := s.topFC()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
193 if !fc.nullable {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
194 s.skipAllChildren = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
195 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
196 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
197
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
198 case ntTestgroup | afterChild:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
199 if CurIndex > 1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
200 child := s.popFC()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
201 cumul := s.topFC()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
202
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
203 s.failed = !cumul.addFC(*child, false)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
204 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
205 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
206
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
207 case ntAlternate | afterChild, ntTestref | afterChild:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
208 if CurIndex != 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
209 child := s.popFC()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
210 cumul := s.topFC()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
211
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
212 s.failed = !cumul.addFC(*child, false)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
213 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
214 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
215
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
216 case ntLoop | afterChild, ntLazyloop | afterChild:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
217 if node.m == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
218 fc := s.topFC()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
219 fc.nullable = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
220 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
221 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
222
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
223 case ntGroup | beforeChild, ntGroup | afterChild, ntCapture | beforeChild, ntCapture | afterChild, ntGreedy | beforeChild, ntGreedy | afterChild:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
224 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
225
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
226 case ntRequire | beforeChild, ntPrevent | beforeChild:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
227 s.skipChild()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
228 s.pushFC(regexFc{nullable: true})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
229 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
230
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
231 case ntRequire | afterChild, ntPrevent | afterChild:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
232 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
233
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
234 case ntOne, ntNotone:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
235 s.pushFC(newRegexFc(node.ch, nt == ntNotone, false, ci))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
236 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
237
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
238 case ntOneloop, ntOnelazy:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
239 s.pushFC(newRegexFc(node.ch, false, node.m == 0, ci))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
240 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
241
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
242 case ntNotoneloop, ntNotonelazy:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
243 s.pushFC(newRegexFc(node.ch, true, node.m == 0, ci))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
244 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
245
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
246 case ntMulti:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
247 if len(node.str) == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
248 s.pushFC(regexFc{nullable: true})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
249 } else if !rtl {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
250 s.pushFC(newRegexFc(node.str[0], false, false, ci))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
251 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
252 s.pushFC(newRegexFc(node.str[len(node.str)-1], false, false, ci))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
253 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
254 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
255
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
256 case ntSet:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
257 s.pushFC(regexFc{cc: node.set.Copy(), nullable: false, caseInsensitive: ci})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
258 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
259
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
260 case ntSetloop, ntSetlazy:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
261 s.pushFC(regexFc{cc: node.set.Copy(), nullable: node.m == 0, caseInsensitive: ci})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
262 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
263
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
264 case ntRef:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
265 s.pushFC(regexFc{cc: *AnyClass(), nullable: true, caseInsensitive: false})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
266 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
267
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
268 case ntNothing, ntBol, ntEol, ntBoundary, ntNonboundary, ntECMABoundary, ntNonECMABoundary, ntBeginning, ntStart, ntEndZ, ntEnd:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
269 s.pushFC(regexFc{nullable: true})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
270 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
271
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
272 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
273 panic(fmt.Sprintf("unexpected op code: %v", nt))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
274 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
275 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
276
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
277 type regexFc struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
278 cc CharSet
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
279 nullable bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
280 caseInsensitive bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
281 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
282
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
283 func newRegexFc(ch rune, not, nullable, caseInsensitive bool) regexFc {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
284 r := regexFc{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
285 caseInsensitive: caseInsensitive,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
286 nullable: nullable,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
287 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
288 if not {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
289 if ch > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
290 r.cc.addRange('\x00', ch-1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
291 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
292 if ch < 0xFFFF {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
293 r.cc.addRange(ch+1, utf8.MaxRune)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
294 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
295 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
296 r.cc.addRange(ch, ch)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
297 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
298 return r
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
299 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
300
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
301 func (r *regexFc) getFirstChars() CharSet {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
302 if r.caseInsensitive {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
303 r.cc.addLowercase()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
304 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
305
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
306 return r.cc
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
307 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
308
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
309 func (r *regexFc) addFC(fc regexFc, concatenate bool) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
310 if !r.cc.IsMergeable() || !fc.cc.IsMergeable() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
311 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
312 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
313
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
314 if concatenate {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
315 if !r.nullable {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
316 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
317 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
318
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
319 if !fc.nullable {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
320 r.nullable = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
321 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
322 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
323 if fc.nullable {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
324 r.nullable = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
325 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
326 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
327
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
328 r.caseInsensitive = r.caseInsensitive || fc.caseInsensitive
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
329 r.cc.addSet(fc.cc)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
330
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
331 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
332 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
333
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
334 // This is a related computation: it takes a RegexTree and computes the
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
335 // leading substring if it sees one. It's quite trivial and gives up easily.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
336 func getPrefix(tree *RegexTree) *Prefix {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
337 var concatNode *regexNode
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
338 nextChild := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
339
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
340 curNode := tree.root
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
341
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
342 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
343 switch curNode.t {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
344 case ntConcatenate:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
345 if len(curNode.children) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
346 concatNode = curNode
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
347 nextChild = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
348 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
349
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
350 case ntGreedy, ntCapture:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
351 curNode = curNode.children[0]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
352 concatNode = nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
353 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
354
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
355 case ntOneloop, ntOnelazy:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
356 if curNode.m > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
357 return &Prefix{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
358 PrefixStr: repeat(curNode.ch, curNode.m),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
359 CaseInsensitive: (curNode.options & IgnoreCase) != 0,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
360 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
361 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
362 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
363
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
364 case ntOne:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
365 return &Prefix{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
366 PrefixStr: []rune{curNode.ch},
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
367 CaseInsensitive: (curNode.options & IgnoreCase) != 0,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
368 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
369
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
370 case ntMulti:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
371 return &Prefix{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
372 PrefixStr: curNode.str,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
373 CaseInsensitive: (curNode.options & IgnoreCase) != 0,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
374 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
375
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
376 case ntBol, ntEol, ntBoundary, ntECMABoundary, ntBeginning, ntStart,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
377 ntEndZ, ntEnd, ntEmpty, ntRequire, ntPrevent:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
378
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
379 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
380 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
381 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
382
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
383 if concatNode == nil || nextChild >= len(concatNode.children) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
384 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
385 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
386
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
387 curNode = concatNode.children[nextChild]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
388 nextChild++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
389 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
390 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
391
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
392 // repeat the rune r, c times... up to the max of MaxPrefixSize
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
393 func repeat(r rune, c int) []rune {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
394 if c > MaxPrefixSize {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
395 c = MaxPrefixSize
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
396 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
397
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
398 ret := make([]rune, c)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
399
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
400 // binary growth using copy for speed
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
401 ret[0] = r
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
402 bp := 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
403 for bp < len(ret) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
404 copy(ret[bp:], ret[:bp])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
405 bp *= 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
406 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
407
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
408 return ret
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
409 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
410
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
411 // BmPrefix precomputes the Boyer-Moore
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
412 // tables for fast string scanning. These tables allow
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
413 // you to scan for the first occurrence of a string within
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
414 // a large body of text without examining every character.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
415 // The performance of the heuristic depends on the actual
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
416 // string and the text being searched, but usually, the longer
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
417 // the string that is being searched for, the fewer characters
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
418 // need to be examined.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
419 type BmPrefix struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
420 positive []int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
421 negativeASCII []int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
422 negativeUnicode [][]int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
423 pattern []rune
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
424 lowASCII rune
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
425 highASCII rune
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
426 rightToLeft bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
427 caseInsensitive bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
428 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
429
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
430 func newBmPrefix(pattern []rune, caseInsensitive, rightToLeft bool) *BmPrefix {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
431
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
432 b := &BmPrefix{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
433 rightToLeft: rightToLeft,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
434 caseInsensitive: caseInsensitive,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
435 pattern: pattern,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
436 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
437
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
438 if caseInsensitive {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
439 for i := 0; i < len(b.pattern); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
440 // We do the ToLower character by character for consistency. With surrogate chars, doing
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
441 // a ToLower on the entire string could actually change the surrogate pair. This is more correct
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
442 // linguistically, but since Regex doesn't support surrogates, it's more important to be
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
443 // consistent.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
444
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
445 b.pattern[i] = unicode.ToLower(b.pattern[i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
446 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
447 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
448
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
449 var beforefirst, last, bump int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
450 var scan, match int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
451
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
452 if !rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
453 beforefirst = -1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
454 last = len(b.pattern) - 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
455 bump = 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
456 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
457 beforefirst = len(b.pattern)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
458 last = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
459 bump = -1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
460 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
461
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
462 // PART I - the good-suffix shift table
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
463 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
464 // compute the positive requirement:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
465 // if char "i" is the first one from the right that doesn't match,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
466 // then we know the matcher can advance by _positive[i].
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
467 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
468 // This algorithm is a simplified variant of the standard
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
469 // Boyer-Moore good suffix calculation.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
470
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
471 b.positive = make([]int, len(b.pattern))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
472
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
473 examine := last
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
474 ch := b.pattern[examine]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
475 b.positive[examine] = bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
476 examine -= bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
477
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
478 Outerloop:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
479 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
480 // find an internal char (examine) that matches the tail
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
481
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
482 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
483 if examine == beforefirst {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
484 break Outerloop
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
485 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
486 if b.pattern[examine] == ch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
487 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
488 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
489 examine -= bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
490 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
491
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
492 match = last
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
493 scan = examine
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
494
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
495 // find the length of the match
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
496 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
497 if scan == beforefirst || b.pattern[match] != b.pattern[scan] {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
498 // at the end of the match, note the difference in _positive
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
499 // this is not the length of the match, but the distance from the internal match
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
500 // to the tail suffix.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
501 if b.positive[match] == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
502 b.positive[match] = match - scan
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
503 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
504
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
505 // System.Diagnostics.Debug.WriteLine("Set positive[" + match + "] to " + (match - scan));
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
506
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
507 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
508 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
509
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
510 scan -= bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
511 match -= bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
512 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
513
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
514 examine -= bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
515 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
516
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
517 match = last - bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
518
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
519 // scan for the chars for which there are no shifts that yield a different candidate
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
520
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
521 // The inside of the if statement used to say
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
522 // "_positive[match] = last - beforefirst;"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
523 // This is slightly less aggressive in how much we skip, but at worst it
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
524 // should mean a little more work rather than skipping a potential match.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
525 for match != beforefirst {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
526 if b.positive[match] == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
527 b.positive[match] = bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
528 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
529
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
530 match -= bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
531 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
532
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
533 // PART II - the bad-character shift table
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
534 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
535 // compute the negative requirement:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
536 // if char "ch" is the reject character when testing position "i",
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
537 // we can slide up by _negative[ch];
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
538 // (_negative[ch] = str.Length - 1 - str.LastIndexOf(ch))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
539 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
540 // the lookup table is divided into ASCII and Unicode portions;
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
541 // only those parts of the Unicode 16-bit code set that actually
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
542 // appear in the string are in the table. (Maximum size with
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
543 // Unicode is 65K; ASCII only case is 512 bytes.)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
544
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
545 b.negativeASCII = make([]int, 128)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
546
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
547 for i := 0; i < len(b.negativeASCII); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
548 b.negativeASCII[i] = last - beforefirst
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
549 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
550
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
551 b.lowASCII = 127
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
552 b.highASCII = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
553
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
554 for examine = last; examine != beforefirst; examine -= bump {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
555 ch = b.pattern[examine]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
556
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
557 switch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
558 case ch < 128:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
559 if b.lowASCII > ch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
560 b.lowASCII = ch
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
561 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
562
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
563 if b.highASCII < ch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
564 b.highASCII = ch
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
565 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
566
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
567 if b.negativeASCII[ch] == last-beforefirst {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
568 b.negativeASCII[ch] = last - examine
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
569 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
570 case ch <= 0xffff:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
571 i, j := ch>>8, ch&0xFF
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
572
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
573 if b.negativeUnicode == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
574 b.negativeUnicode = make([][]int, 256)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
575 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
576
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
577 if b.negativeUnicode[i] == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
578 newarray := make([]int, 256)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
579
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
580 for k := 0; k < len(newarray); k++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
581 newarray[k] = last - beforefirst
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
582 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
583
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
584 if i == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
585 copy(newarray, b.negativeASCII)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
586 //TODO: this line needed?
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
587 b.negativeASCII = newarray
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
588 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
589
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
590 b.negativeUnicode[i] = newarray
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
591 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
592
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
593 if b.negativeUnicode[i][j] == last-beforefirst {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
594 b.negativeUnicode[i][j] = last - examine
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
595 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
596 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
597 // we can't do the filter because this algo doesn't support
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
598 // unicode chars >0xffff
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
599 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
600 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
601 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
602
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
603 return b
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
604 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
605
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
606 func (b *BmPrefix) String() string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
607 return string(b.pattern)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
608 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
609
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
610 // Dump returns the contents of the filter as a human readable string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
611 func (b *BmPrefix) Dump(indent string) string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
612 buf := &bytes.Buffer{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
613
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
614 fmt.Fprintf(buf, "%sBM Pattern: %s\n%sPositive: ", indent, string(b.pattern), indent)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
615 for i := 0; i < len(b.positive); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
616 buf.WriteString(strconv.Itoa(b.positive[i]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
617 buf.WriteRune(' ')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
618 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
619 buf.WriteRune('\n')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
620
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
621 if b.negativeASCII != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
622 buf.WriteString(indent)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
623 buf.WriteString("Negative table\n")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
624 for i := 0; i < len(b.negativeASCII); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
625 if b.negativeASCII[i] != len(b.pattern) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
626 fmt.Fprintf(buf, "%s %s %s\n", indent, Escape(string(rune(i))), strconv.Itoa(b.negativeASCII[i]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
627 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
628 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
629 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
630
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
631 return buf.String()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
632 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
633
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
634 // Scan uses the Boyer-Moore algorithm to find the first occurrence
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
635 // of the specified string within text, beginning at index, and
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
636 // constrained within beglimit and endlimit.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
637 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
638 // The direction and case-sensitivity of the match is determined
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
639 // by the arguments to the RegexBoyerMoore constructor.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
640 func (b *BmPrefix) Scan(text []rune, index, beglimit, endlimit int) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
641 var (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
642 defadv, test, test2 int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
643 match, startmatch, endmatch int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
644 bump, advance int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
645 chTest rune
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
646 unicodeLookup []int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
647 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
648
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
649 if !b.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
650 defadv = len(b.pattern)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
651 startmatch = len(b.pattern) - 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
652 endmatch = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
653 test = index + defadv - 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
654 bump = 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
655 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
656 defadv = -len(b.pattern)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
657 startmatch = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
658 endmatch = -defadv - 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
659 test = index + defadv
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
660 bump = -1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
661 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
662
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
663 chMatch := b.pattern[startmatch]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
664
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
665 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
666 if test >= endlimit || test < beglimit {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
667 return -1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
668 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
669
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
670 chTest = text[test]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
671
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
672 if b.caseInsensitive {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
673 chTest = unicode.ToLower(chTest)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
674 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
675
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
676 if chTest != chMatch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
677 if chTest < 128 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
678 advance = b.negativeASCII[chTest]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
679 } else if chTest < 0xffff && len(b.negativeUnicode) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
680 unicodeLookup = b.negativeUnicode[chTest>>8]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
681 if len(unicodeLookup) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
682 advance = unicodeLookup[chTest&0xFF]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
683 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
684 advance = defadv
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
685 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
686 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
687 advance = defadv
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
688 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
689
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
690 test += advance
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
691 } else { // if (chTest == chMatch)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
692 test2 = test
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
693 match = startmatch
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
694
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
695 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
696 if match == endmatch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
697 if b.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
698 return test2 + 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
699 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
700 return test2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
701 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
702 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
703
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
704 match -= bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
705 test2 -= bump
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
706
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
707 chTest = text[test2]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
708
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
709 if b.caseInsensitive {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
710 chTest = unicode.ToLower(chTest)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
711 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
712
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
713 if chTest != b.pattern[match] {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
714 advance = b.positive[match]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
715 if (chTest & 0xFF80) == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
716 test2 = (match - startmatch) + b.negativeASCII[chTest]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
717 } else if chTest < 0xffff && len(b.negativeUnicode) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
718 unicodeLookup = b.negativeUnicode[chTest>>8]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
719 if len(unicodeLookup) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
720 test2 = (match - startmatch) + unicodeLookup[chTest&0xFF]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
721 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
722 test += advance
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
723 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
724 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
725 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
726 test += advance
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
727 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
728 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
729
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
730 if b.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
731 if test2 < advance {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
732 advance = test2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
733 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
734 } else if test2 > advance {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
735 advance = test2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
736 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
737
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
738 test += advance
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
739 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
740 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
741 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
742 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
743 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
744 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
745
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
746 // When a regex is anchored, we can do a quick IsMatch test instead of a Scan
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
747 func (b *BmPrefix) IsMatch(text []rune, index, beglimit, endlimit int) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
748 if !b.rightToLeft {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
749 if index < beglimit || endlimit-index < len(b.pattern) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
750 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
751 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
752
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
753 return b.matchPattern(text, index)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
754 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
755 if index > endlimit || index-beglimit < len(b.pattern) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
756 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
757 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
758
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
759 return b.matchPattern(text, index-len(b.pattern))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
760 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
761 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
762
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
763 func (b *BmPrefix) matchPattern(text []rune, index int) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
764 if len(text)-index < len(b.pattern) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
765 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
766 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
767
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
768 if b.caseInsensitive {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
769 for i := 0; i < len(b.pattern); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
770 //Debug.Assert(textinfo.ToLower(_pattern[i]) == _pattern[i], "pattern should be converted to lower case in constructor!");
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
771 if unicode.ToLower(text[index+i]) != b.pattern[i] {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
772 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
773 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
774 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
775 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
776 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
777 for i := 0; i < len(b.pattern); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
778 if text[index+i] != b.pattern[i] {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
779 return false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
780 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
781 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
782 return true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
783 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
784 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
785
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
786 type AnchorLoc int16
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
787
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
788 // where the regex can be pegged
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
789 const (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
790 AnchorBeginning AnchorLoc = 0x0001
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
791 AnchorBol = 0x0002
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
792 AnchorStart = 0x0004
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
793 AnchorEol = 0x0008
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
794 AnchorEndZ = 0x0010
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
795 AnchorEnd = 0x0020
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
796 AnchorBoundary = 0x0040
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
797 AnchorECMABoundary = 0x0080
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
798 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
799
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
800 func getAnchors(tree *RegexTree) AnchorLoc {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
801
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
802 var concatNode *regexNode
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
803 nextChild, result := 0, AnchorLoc(0)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
804
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
805 curNode := tree.root
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
806
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
807 for {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
808 switch curNode.t {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
809 case ntConcatenate:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
810 if len(curNode.children) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
811 concatNode = curNode
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
812 nextChild = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
813 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
814
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
815 case ntGreedy, ntCapture:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
816 curNode = curNode.children[0]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
817 concatNode = nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
818 continue
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
819
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
820 case ntBol, ntEol, ntBoundary, ntECMABoundary, ntBeginning,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
821 ntStart, ntEndZ, ntEnd:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
822 return result | anchorFromType(curNode.t)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
823
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
824 case ntEmpty, ntRequire, ntPrevent:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
825
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
826 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
827 return result
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
828 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
829
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
830 if concatNode == nil || nextChild >= len(concatNode.children) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
831 return result
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
832 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
833
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
834 curNode = concatNode.children[nextChild]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
835 nextChild++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
836 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
837 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
838
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
839 func anchorFromType(t nodeType) AnchorLoc {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
840 switch t {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
841 case ntBol:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
842 return AnchorBol
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
843 case ntEol:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
844 return AnchorEol
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
845 case ntBoundary:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
846 return AnchorBoundary
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
847 case ntECMABoundary:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
848 return AnchorECMABoundary
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
849 case ntBeginning:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
850 return AnchorBeginning
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
851 case ntStart:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
852 return AnchorStart
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
853 case ntEndZ:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
854 return AnchorEndZ
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
855 case ntEnd:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
856 return AnchorEnd
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
857 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
858 return 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
859 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
860 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
861
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
862 // anchorDescription returns a human-readable description of the anchors
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
863 func (anchors AnchorLoc) String() string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
864 buf := &bytes.Buffer{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
865
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
866 if 0 != (anchors & AnchorBeginning) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
867 buf.WriteString(", Beginning")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
868 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
869 if 0 != (anchors & AnchorStart) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
870 buf.WriteString(", Start")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
871 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
872 if 0 != (anchors & AnchorBol) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
873 buf.WriteString(", Bol")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
874 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
875 if 0 != (anchors & AnchorBoundary) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
876 buf.WriteString(", Boundary")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
877 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
878 if 0 != (anchors & AnchorECMABoundary) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
879 buf.WriteString(", ECMABoundary")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
880 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
881 if 0 != (anchors & AnchorEol) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
882 buf.WriteString(", Eol")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
883 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
884 if 0 != (anchors & AnchorEnd) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
885 buf.WriteString(", End")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
886 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
887 if 0 != (anchors & AnchorEndZ) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
888 buf.WriteString(", EndZ")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
889 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
890
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
891 // trim off comma
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
892 if buf.Len() >= 2 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
893 return buf.String()[2:]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
894 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
895 return "None"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
896 }