Added some error handling to the Excellon parser.

This commit is contained in:
jpcaram
2015-01-10 19:01:12 -05:00
parent d0eff0f25d
commit 207842f98f
2 changed files with 108 additions and 86 deletions

View File

@@ -1610,7 +1610,13 @@ class App(QtCore.QObject):
self.progress.emit(0) # TODO: self and app_bjj mixed self.progress.emit(0) # TODO: self and app_bjj mixed
raise IOError("Cannot open file: " + filename) raise IOError("Cannot open file: " + filename)
try:
excellon_obj.create_geometry() excellon_obj.create_geometry()
except Exception as e:
app_obj.inform.emit("[error] Failed to create geometry after parsing: " + filename)
self.progress.emit(0)
raise e
self.progress.emit(70) self.progress.emit(70)
# Object name # Object name

View File

@@ -51,6 +51,10 @@ handler.setFormatter(formatter)
log.addHandler(handler) log.addHandler(handler)
class ParseError(Exception):
pass
class Geometry(object): class Geometry(object):
""" """
Base geometry class. Base geometry class.
@@ -1781,7 +1785,8 @@ class Excellon(Geometry):
self.hend_re = re.compile(r'^(?:M95|%)$') self.hend_re = re.compile(r'^(?:M95|%)$')
# FMAT Excellon format # FMAT Excellon format
self.fmat_re = re.compile(r'^FMAT,([12])$') # Ignored in the parser
#self.fmat_re = re.compile(r'^FMAT,([12])$')
# Number format and units # Number format and units
# INCH uses 6 digits # INCH uses 6 digits
@@ -1866,13 +1871,16 @@ class Excellon(Geometry):
#### Parsing starts here #### #### Parsing starts here ####
line_num = 0 # Line number line_num = 0 # Line number
eline = ""
try:
for eline in elines: for eline in elines:
line_num += 1 line_num += 1
log.debug("%3d %s" % (line_num, str(eline)))
### Cleanup lines ### Cleanup lines
eline = eline.strip(' \r\n') eline = eline.strip(' \r\n')
## Header Begin/End ## ## Header Begin (M48) / End (M95) ##
if self.hbegin_re.search(eline): if self.hbegin_re.search(eline):
in_header = True in_header = True
continue continue
@@ -1888,6 +1896,7 @@ class Excellon(Geometry):
match = self.toolsel_re.search(eline) match = self.toolsel_re.search(eline)
if match: if match:
current_tool = str(int(match.group(1))) current_tool = str(int(match.group(1)))
log.debug("Tool change: %s" % current_tool)
continue continue
## Coordinates without period ## ## Coordinates without period ##
@@ -1942,6 +1951,7 @@ class Excellon(Geometry):
## Tool definitions ## ## Tool definitions ##
match = self.toolset_re.search(eline) match = self.toolset_re.search(eline)
if match: if match:
name = str(int(match.group(1))) name = str(int(match.group(1)))
spec = { spec = {
"C": float(match.group(2)), "C": float(match.group(2)),
@@ -1952,6 +1962,7 @@ class Excellon(Geometry):
# "Z": float(match.group(7)) # "Z": float(match.group(7))
} }
self.tools[name] = spec self.tools[name] = spec
log.debug(" Tool definition: %s %s" % (name, spec))
continue continue
## Units and number format ## ## Units and number format ##
@@ -1959,12 +1970,17 @@ class Excellon(Geometry):
if match: if match:
self.zeros = match.group(2) or self.zeros # "T" or "L". Might be empty self.zeros = match.group(2) or self.zeros # "T" or "L". Might be empty
self.units = {"INCH": "IN", "METRIC": "MM"}[match.group(1)] self.units = {"INCH": "IN", "METRIC": "MM"}[match.group(1)]
log.debug(" Units/Format: %s %s" % (self.units, self.zeros))
continue continue
log.warning("Line ignored: %s" % eline) log.warning("Line ignored: %s" % eline)
log.info("Zeros: %s, Units %s." % (self.zeros, self.units)) log.info("Zeros: %s, Units %s." % (self.zeros, self.units))
except Exception as e:
log.error("PARSING FAILED. Line %d: %s" % (line_num, eline))
raise
def parse_number(self, number_str): def parse_number(self, number_str):
""" """
Parses coordinate numbers without period. Parses coordinate numbers without period.