1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
#!/usr/bin/env python
"""
Defines LineSplitter.
Copyright 2006 Pearu Peterson all rights reserved,
Pearu Peterson <pearu@cens.ioc.ee>
Permission to use, modify, and distribute this software is given under the
terms of the LGPL. See http://www.fsf.org
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
$Revision:$
$Date: 2000/07/31 07:04:03 $
Pearu Peterson
"""
__all__ = ['LineSplitter','String']
class String(str): pass
class LineSplitter:
""" Splits a line into non strings and strings. E.g.
abc=\"123\" -> ['abc=','\"123\"']
Handles splitting lines with incomplete string blocks.
"""
def __init__(self, line, quotechar = None, lower=False):
self.fifo_line = [c for c in line]
self.fifo_line.reverse()
self.quotechar = quotechar
self.lower = lower
def __iter__(self):
return self
def next(self):
item = ''
while not item:
item = self.get_item() # get_item raises StopIteration
return item
def get_item(self):
fifo_pop = self.fifo_line.pop
try:
char = fifo_pop()
except IndexError:
raise StopIteration
fifo_append = self.fifo_line.append
quotechar = self.quotechar
l = []
l_append = l.append
nofslashes = 0
if quotechar is None:
# search for string start
while 1:
if char in '"\'' and not nofslashes % 2:
self.quotechar = char
fifo_append(char)
break
if char=='\\':
nofslashes += 1
else:
nofslashes = 0
l_append(char)
try:
char = fifo_pop()
except IndexError:
break
item = ''.join(l)
if self.lower: item = item.lower()
return item
if char==quotechar:
# string starts with quotechar
l_append(char)
try:
char = fifo_pop()
except IndexError:
return String(''.join(l))
# else continued string
while 1:
if char==quotechar and not nofslashes % 2:
l_append(char)
self.quotechar = None
break
if char=='\\':
nofslashes += 1
else:
nofslashes = 0
l_append(char)
try:
char = fifo_pop()
except IndexError:
break
return String(''.join(l))
def test():
splitter = LineSplitter('abc\\\' def"12\\"3""56"dfad\'a d\'')
l = [item for item in splitter]
assert l==['abc\\\' def','"12\\"3"','"56"','dfad','\'a d\''],`l`
assert splitter.quotechar is None
splitter = LineSplitter('"abc123&')
l = [item for item in splitter]
assert l==['"abc123&'],`l`
assert splitter.quotechar=='"'
splitter = LineSplitter(' &abc"123','"')
l = [item for item in splitter]
assert l==[' &abc"','123']
assert splitter.quotechar is None
if __name__ == '__main__':
test()
|