-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathrtlparser.py
More file actions
144 lines (122 loc) · 4.71 KB
/
Copy pathrtlparser.py
File metadata and controls
144 lines (122 loc) · 4.71 KB
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#
# Utility functions for parsing RTL files
#
import sys
import re
import itertools
# Returns a list with position [x,y]
def parsePosition(pos):
return pos.split(',')
# Returns a list of positions [x0, y0, x1, y1 ...]
def parsePointlist(pointlist):
return pointlist.split(',')
class RTLParser:
def __init__(self, verbose=False):
self.verbose = verbose
self.reset()
self.handlers = {}
self.commandregexp = re.compile("([a-zA-Z]+)([0-9,]*);")
self.coordregexp = re.compile("[0-9]+,[0-9]+$")
self.coordsregexp = re.compile("[0-9]+(,[0-9]+)+$")
def reset(self):
self.bbox = [[sys.maxint, sys.maxint],[0, 0]]
self.startpos = self.currpos = None
self.strokelist = None
def registerHandler(self, primitive, func):
self.handlers[primitive] = func
def parse(self, rtlfile):
f = open(rtlfile, "rb")
buffer = f.read()
# Look for start of HP-GL/2 section
pos = buffer.find("\x1b%1BIN;")
if pos < 0: return
else: pos += 7
hpglend = buffer.find('\x1b%0B', pos)
if hpglend == -1:
print "Error: End of HP/GL-2 section not found"
exit(1)
prevpos = pos;
while pos < hpglend:
# This signifies the end of HP-GL/2 section
if buffer[pos] == '\x1b%0B': break
end = buffer.find(";", pos, hpglend)
if end == -1:
print "Error: Command not terminated: '" + buffer[pos:hpglend] + "'"
print " Previous command: '" + buffer[prevpos:pos] + "'"
exit(1)
if end == pos:
print "Error: Unexpected ';' at '" + buffer[pos-10:pos+1]
exit(1)
self.parseCommand(buffer, pos, end)
prevpos = pos
pos = end + 1
# FIXME: Assert that there aren't more HP-GL/2 sections
# Implicit PU when ending
self.handlePU(None);
def parseCommand(self, buffer, pos, end):
# Extract the command and args
if self.verbose:
pend = end
if end - pos > 30: pend = pos + 30
if self.verbose: print "cmd: " + buffer[pos:pend],
if end - pos > 30: print "..."
else: print
m = self.commandregexp.match(buffer, pos, end+1)
# Call handler function
funcname = "handle%s" % m.group(1)
if hasattr(self, funcname):
getattr(self, funcname)(m.group(2))
else:
print "Error: Unknown command '" + m.group(1) + "'"
def expandBBox(self, x, y):
if x < self.bbox[0][0]: self.bbox[0][0] = x
if x > self.bbox[1][0]: self.bbox[1][0] = x
if y < self.bbox[0][1]: self.bbox[0][1] = y
if y > self.bbox[1][1]: self.bbox[1][1] = y
def handleYP(self, power):
if self.verbose: print "YP " + power
if "YP" in self.handlers:
self.handlers["YP"](power)
def handleZS(self, speed):
if self.verbose: print "ZS " + speed
if "ZS" in self.handlers:
self.handlers["ZS"](speed)
def handleXR(self, freq):
if self.verbose: print "XR " + freq
if "XR" in self.handlers:
self.handlers["XR"](freq)
# pos is a coordinate (x,y)
def handlePU(self, pos):
assert(pos == None or self.coordregexp.match(pos))
if self.verbose: print "PU " + str(pos)
strokestr = ""
if self.strokelist != None:
if self.verbose: print("new stroke")
self.strokelist.insert(0, self.startpos)
for p in self.strokelist:
self.expandBBox(int(p[0]), int(p[1]))
strokestr += "%s,%s " % (p[0], p[1])
# if self.verbose: print(strokestr)
if "PU" in self.handlers:
self.handlers["PU"](pos, strokestr)
if pos and len(pos) > 0: self.currpos = parsePosition(pos)
self.startpos = None
def handleLTPU(self, pos):
if self.verbose: print "LT " + pos,
if "LTPU" in self.handlers:
self.handlers["LTPU"](pos)
self.handlePU(pos)
def handlePD(self, pointstr):
assert(self.startpos == None)
assert(self.coordsregexp.match(pointstr))
if self.verbose:
print "PD " + pointstr[0:30],
if len(pointstr) > 30: print "..."
else: print
self.startpos = self.currpos
coordlist = pointstr.split(',')
# Group each pair of coordinates
self.strokelist = list(itertools.izip(*[itertools.islice(coordlist, i, None, 2) for i in range(2)]))
# FIXME: We don't support subsequent PD commands without a PU in between
if "PD" in self.handlers:
self.handlers["PD"](pointstr)