From 1872df4a339b6c3a9e04dd0b55564902871f412d Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 6 Feb 2022 14:20:13 +0100 Subject: Make split_commands faster --- gerbonara/excellon.py | 4 +++- gerbonara/rs274x.py | 27 ++++++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'gerbonara') diff --git a/gerbonara/excellon.py b/gerbonara/excellon.py index 5f0db44..721fcca 100755 --- a/gerbonara/excellon.py +++ b/gerbonara/excellon.py @@ -535,6 +535,7 @@ class ExcellonParser(object): self.lineno = None self.filename = None self.external_tools = external_tools or {} + self.found_kicad_format_comment = False def warn(self, msg): warnings.warn(f'{self.filename}:{self.lineno} "{self.line}": {msg}', SyntaxWarning) @@ -844,7 +845,7 @@ class ExcellonParser(object): integer, _, fractional = match[3][1:].partition('.') self.settings.number_format = len(integer), len(fractional) - elif self.settings.number_format == (None, None) and not metric: + elif self.settings.number_format == (None, None) and not metric and not self.found_kicad_format_comment: self.warn('Using implicit number format from bare "INCH" statement. This is normal for Fritzing, Diptrace, Geda and pcb-rnd.') self.settings.number_format = (2,4) @@ -981,6 +982,7 @@ class ExcellonParser(object): x = None if x == '-' else int(x) y = None if y == '-' else int(y) self.settings.number_format = x, y + self.found_kicad_format_comment = True self.settings.notation = match[2] self.settings.unit = Inch if match[3] == 'inch' else MM diff --git a/gerbonara/rs274x.py b/gerbonara/rs274x.py index 82ee047..e29ecd8 100644 --- a/gerbonara/rs274x.py +++ b/gerbonara/rs274x.py @@ -520,11 +520,11 @@ class GerberParser: NAME = r"[a-zA-Z_$\.][a-zA-Z_$\.0-9+\-]+" STATEMENT_REGEXES = { - 'region_start': r'G36$', - 'region_end': r'G37$', 'coord': fr"(?PG0?[123]|G74|G75|G54|G55)?(X(?P{NUMBER}))?(Y(?P{NUMBER}))?" \ fr"(I(?P{NUMBER}))?(J(?P{NUMBER}))?" \ fr"(?PD0?[123])?$", + 'region_start': r'G36$', + 'region_end': r'G37$', 'aperture': r"(G54|G55)?D(?P\d+)", # Allegro combines format spec and unit into one long illegal extended command. 'allegro_format_spec': r"FS(?P(L|T|D))?(?P(A|I))[NG0-9]*X(?P[0-7][0-7])Y(?P[0-7][0-7])[DM0-9]*\*MO(?PIN|MM)", @@ -581,12 +581,25 @@ class GerberParser: self.lineno = None self.line = None + def _shorten_line(self): + line_joined = self.line.replace('\r', '').replace('\n', '\\n') + if len(line_joined) > 80: + return f'{line_joined[:20]}[...]{line_joined[-20:]}' + else: + return line_joined + def warn(self, msg, kls=SyntaxWarning): - line_joined = self.line.replace('\n', '\\n') - warnings.warn(f'{self.filename}:{self.lineno} "{line_joined}": {msg}', kls) + warnings.warn(f'{self.filename}:{self.lineno} "{self._shorten_line()}": {msg}', kls) @classmethod def _split_commands(kls, data): + for match in re.finditer(r'G04.*?\*|%.*?%|[^*%]*\*', data, re.DOTALL): + cmd = match[0].strip().strip('%').rstrip('*').replace('\r', '').replace('\n', '') + if cmd: + yield 1, cmd + return + + ####### start = 0 extended_command = False lineno = 1 @@ -637,13 +650,13 @@ class GerberParser: try: getattr(self, f'_parse_{name}')(match) except Exception as e: - raise SyntaxError(f'{filename}:{lineno} "{line}": {e}') from e + raise SyntaxError(f'{filename}:{lineno} "{self._shorten_line()}": {e}') from e line = line[match.end(0):] break else: - self.warn(f'Unknown statement found: "{line}", ignoring.', UnknownStatementWarning) - self.target.comments.append(f'Unknown statement found: "{line}", ignoring.') + self.warn(f'Unknown statement found: "{self._shorten_line()}", ignoring.', UnknownStatementWarning) + self.target.comments.append(f'Unknown statement found: "{self._shorten_line()}", ignoring.') self.target.apertures = list(self.aperture_map.values()) self.target.import_settings = self.file_settings -- cgit