From 12227608c4a7976074f1c889c7e86b5852e3133a Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Tue, 28 Feb 2023 13:57:57 -0300 Subject: [PATCH] Added missing files --- kibot/kicad/error.py | 22 +++++ kibot/kicad/sexp_helpers.py | 161 ++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 kibot/kicad/error.py create mode 100644 kibot/kicad/sexp_helpers.py diff --git a/kibot/kicad/error.py b/kibot/kicad/error.py new file mode 100644 index 00000000..0493870d --- /dev/null +++ b/kibot/kicad/error.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2021-2023 Salvador E. Tropea +# Copyright (c) 2021-2023 Instituto Nacional de TecnologĂ­a Industrial +# License: AGPL-3.0 +# Project: KiBot (formerly KiPlot) + +class SchError(Exception): + pass + + +class SchFileError(SchError): + def __init__(self, msg, code, reader): + super().__init__() + self.line = reader.line + self.file = reader.file + self.msg = msg + self.code = code + + +class SchLibError(SchFileError): + def __init__(self, msg, code, reader): + super().__init__(msg, code, reader) diff --git a/kibot/kicad/sexp_helpers.py b/kibot/kicad/sexp_helpers.py new file mode 100644 index 00000000..2807f954 --- /dev/null +++ b/kibot/kicad/sexp_helpers.py @@ -0,0 +1,161 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2021-2023 Salvador E. Tropea +# Copyright (c) 2021-2023 Instituto Nacional de TecnologĂ­a Industrial +# License: AGPL-3.0 +# Project: KiBot (formerly KiPlot) +from .error import SchError +from .sexpdata import Symbol + + +class Point(object): + def __init__(self, items): + super().__init__() + self.x = _check_float(items, 1, 'x coord') + self.y = _check_float(items, 2, 'y coord') + + @staticmethod + def parse(items): + return Point(items) + + +def _check_is_symbol_list(e, allow_orphan_symbol=()): + # Each entry is a list + if not isinstance(e, list): + if isinstance(e, Symbol): + name = e.value() + if name in allow_orphan_symbol: + return name + raise SchError('Orphan symbol `{}`'.format(e.value())) + else: + raise SchError('Orphan data `{}`'.format(e)) + # The first element is a symbol + if not isinstance(e[0], Symbol): + raise SchError('Orphan data `{}`'.format(e[0])) + return e[0].value() + + +def _check_len(items, pos, name): + if len(items) < pos+1: + raise SchError('Missing argument {} in `{}`'.format(pos, name)) + return items[pos] + + +def _check_len_total(items, num, name): + if len(items) != num: + raise SchError('Wrong number of attributes for {} `{}`'.format(name, items)) + + +def _check_symbol(items, pos, name): + value = _check_len(items, pos, name) + if not isinstance(value, Symbol): + raise SchError('{} is not a Symbol `{}`'.format(name, value)) + return value.value() + + +def _check_hide(items, pos, name): + value = _check_symbol(items, pos, name + ' hide') + if value != 'hide': + raise SchError('Found Symbol `{}` when `hide` expected'.format(value)) + return True + + +def _check_integer(items, pos, name): + value = _check_len(items, pos, name) + if not isinstance(value, int): + raise SchError('{} is not an integer `{}`'.format(name, value)) + return value + + +def _check_float(items, pos, name): + value = _check_len(items, pos, name) + if not isinstance(value, (float, int)): + raise SchError('{} is not a float `{}`'.format(name, value)) + return value + + +def _check_str(items, pos, name): + value = _check_len(items, pos, name) + if not isinstance(value, str): + raise SchError('{} is not a string `{}`'.format(name, value)) + return value + + +def _check_relaxed(items, pos, name): + value = _check_len(items, pos, name) + if isinstance(value, str): + return value + if isinstance(value, Symbol): + return value.value() + if isinstance(value, (float, int)): + return str(value) + raise SchError('{} is not a string, Symbol or number `{}`'.format(name, value)) + + +def _check_symbol_value(items, pos, name, sym): + value = _check_len(items, pos, name) + if not isinstance(value, list) or not isinstance(value[0], Symbol) or value[0].value() != sym: + raise SchError('Missing `{}` in `{}`'.format(sym, name)) + return value + + +def _check_symbol_float(items, pos, name, sym): + name += ' ' + sym + values = _check_symbol_value(items, pos, name, sym) + return _check_float(values, 1, name) + + +def _check_symbol_int(items, pos, name, sym): + name += ' ' + sym + values = _check_symbol_value(items, pos, name, sym) + return _check_integer(values, 1, name) + + +def _check_symbol_str(items, pos, name, sym): + name += ' ' + sym + values = _check_symbol_value(items, pos, name, sym) + return _check_str(values, 1, name) + + +def _get_offset(items, pos, name): + value = _check_symbol_value(items, pos, name, 'offset') + return _check_float(value, 1, 'offset') + + +def _get_yes_no(items, pos, name): + sym = _check_symbol(items, pos, name) + return sym == 'yes' + + +def _get_id(items, pos, name): + value = _check_symbol_value(items, pos, name, 'id') + return _check_integer(value, 1, 'id') + + +def _get_at(items, pos, name): + value = _check_symbol_value(items, pos, name, 'at') + angle = 0 + if len(value) > 3: + angle = _check_float(value, 3, 'at angle') + return _check_float(value, 1, 'at x'), _check_float(value, 2, 'at y'), angle + + +def _get_xy(items): + if len(items) != 3: + raise SchError('Point definition with wrong args (`{}`)'.format(items)) + return Point.parse(items) + + +def _get_points(items): + points = [] + for i in items[1:]: + i_type = _check_is_symbol_list(i) + if i_type == 'xy': + points.append(_get_xy(i)) + else: + raise SchError('Unknown points attribute `{}`'.format(i)) + return points + + +def _get_size(items, pos, name): + value = _check_symbol_value(items, pos, name, 'size') + return _get_xy(value)