Skip to content

Commit b33cd0d

Browse files
committed
make it gc-safe
1 parent 2d33c3a commit b33cd0d

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

q.nim

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ import xmltree
1616
from streams import newStringStream
1717
from strtabs import hasKey
1818

19-
20-
let
21-
attribute = r"[a-zA-Z][a-zA-Z0-9_\-]*"
22-
classes = r"{\.[a-zA-Z0-9_][a-zA-Z0-9_\-]*}"
23-
attributes = r"{\[" & attribute & r"\s*([\*\^\$\~]?\=\s*[\'""]?(\s*\ident\s*)+[\'""]?)?\]}"
24-
pselectors = peg(r"\s*{\ident}?({'#'\ident})? (" & classes & ")* " & attributes & "*")
25-
pattributes = peg(r"{\[{" & attribute & r"}\s*({[\*\^\$\~]?}\=\s*[\'""]?{(\s*\ident\s*)+}[\'""]?)?\]}")
26-
2719
type
2820
Attribute = object
2921
name: string
@@ -36,17 +28,27 @@ type
3628
id: string
3729
classes: seq[string]
3830
attributes: seq[Attribute]
31+
pSelectors: Peg
32+
pAttributes: Peg
3933

4034
QueryContext = object
4135
root: seq[XmlNode]
4236

4337
proc newSelector(tag, id = "", classes: seq[string] = @[], attributes: seq[Attribute] = @[]): Selector =
38+
let
39+
attributeSelector = r"[a-zA-Z][a-zA-Z0-9_\-]*"
40+
classesSelector = r"{\.[a-zA-Z0-9_][a-zA-Z0-9_\-]*}"
41+
attributesSelector = r"{\[" & attributeSelector & r"\s*([\*\^\$\~]?\=\s*[\'""]?(\s*\ident\s*)+[\'""]?)?\]}"
42+
4443
result.combinator = ' '
4544
result.tag = tag
4645
result.id = id
4746
result.classes = classes
4847
result.attributes = attributes
4948

49+
result.pSelectors = peg(r"\s*{\ident}?({'#'\ident})? (" & classesSelector & ")* " & attributesSelector & "*")
50+
result.pAttributes = peg(r"{\[{" & attributeSelector & r"}\s*({[\*\^\$\~]?}\=\s*[\'""]?{(\s*\ident\s*)+}[\'""]?)?\]}")
51+
5052
proc initContext(root: seq[XmlNode]): QueryContext =
5153
result.root = root
5254

@@ -166,13 +168,13 @@ proc searchCombined(parents: var seq[XmlNode], selectors: seq[Selector]) =
166168

167169
parents = found
168170

169-
proc parseSelector(token: string): Selector =
171+
proc parseSelector(token: string): Selector {.gcsafe.} =
170172
result = newSelector()
171173
# Universal selector
172174
if token == "*":
173175
result.tag = "*"
174176
# Type selector
175-
elif token =~ pselectors:
177+
elif token =~ result.pSelectors:
176178
for i in 0..matches.len-1:
177179
if matches[i].len == 0:
178180
continue
@@ -184,16 +186,16 @@ proc parseSelector(token: string): Selector =
184186
result.id = matches[i]
185187
of '.':
186188
matches[i].delete(0, 0)
187-
result.classes.add(matches[i])
189+
result.classes.add(move matches[i])
188190
of '[':
189-
if matches[i] =~ pattributes:
191+
if matches[i] =~ result.pAttributes:
190192
result.attributes.add(newAttribute(matches[1], matches[2], matches[3]))
191193
else:
192194
result.tag = matches[i]
193195
else:
194196
discard
195197

196-
proc select*(q: QueryContext, s: string = ""): seq[XmlNode] =
198+
proc select*(q: QueryContext, s: string = ""): seq[XmlNode] {.gcsafe.} =
197199
## Return list of nodes matched by CSS selector
198200
result = q.root
199201

0 commit comments

Comments
 (0)