Beispiel #1
0
    def parse(self):
        '''Returns a Design built up from a schematic file that represents one
        sheet of the original schematic'''
        tree = ViewDrawBase.parse(self)
        # tree['lines'] is a [list of [list of lines]]
        tree['shape'].extend(sum(tree['lines'], []))
        ckt = Design()
        # TODO little weak here, a copy instead?
        ckt.components = self.lib

        for net in tree['net']:
            ckt.add_net(net)
        for inst in tree['inst']:
            ckt.add_component_instance(inst)
            # hold on tight, this is ugly
            for (netid, netpt, pinid) in inst.conns:
                net = [n for n in ckt.nets if n.net_id == netid][0]
                comp = ConnectedComponent(inst.instance_id, pinid)
                net.ibpts[netpt - 1].add_connected_component(comp)
            del inst.conns
        for net in ckt.nets:
            del net.ibpts

        for shape in tree['shape']:
            ckt.add_shape(shape)
            if isinstance(shape, Label):
                ann = Annotation(shape.text, shape.x, shape.y, shape._rotation,
                                 True)
                ckt.design_attributes.add_annotation(ann)

        for k, v, annot in tree['attr']:
            ckt.design_attributes.add_attribute(k, v)
            ckt.design_attributes.add_annotation(annot)

        return ckt
Beispiel #2
0
    def parse(self, filename, library_filename=None):
        """ Parse a kicad file into a design """

        design = Design()
        segments = set()  # each wire segment
        junctions = set()  # wire junction point (connects all wires under it)

        self.instance_names = []

        self.library = KiCADLibrary()

        if library_filename is None:
            directory, _ = split(filename)
            for dir_file in listdir(directory):
                if dir_file.endswith('.lib'):
                    self.library.parse(directory + '/' + dir_file)

        for cpt in self.library.components:
            design.add_component(cpt.name, cpt)

        with open(filename) as f:
            libs = []
            line = f.readline().strip()

            # parse the library references
            while line and line != "$EndDescr":
                if line.startswith('LIBS:'):
                    libs.extend(line.split(':', 1)[1].split(','))
                line = f.readline().strip()

            # Now parse wires and components, ignore connections, we get
            # connectivity from wire segments

            line = f.readline()

            while line:
                prefix = line.split()[0]

                if line.startswith('Wire Wire Line'):
                    self.parse_wire(f, segments)
                elif prefix == "Connection":  # Store these to apply later
                    self.parse_connection(line, junctions)
                elif prefix == "Text":
                    design.design_attributes.add_annotation(
                        self.parse_text(f, line))
                elif prefix == "$Comp":  # Component Instance
                    inst, comp = self.parse_component_instance(f)
                    design.add_component_instance(inst)
                    if comp is not None:
                        design.add_component(comp.name, comp)
                    self.ensure_component(design, inst.library_id, libs)

                line = f.readline()

        segments = self.divide(segments, junctions)
        design.nets = self.calc_nets(design, segments)

        design.scale(MULT)

        return design
    def __init__(self):
        self.design = Design()

        # map (component, gate name) to body indices
        self.cptgate2body_index = {}

        # map (component, gate name) to pin maps, dicts from strings
        # (pin names) to Pins. These are used during pinref processing
        # in segments.
        self.cptgate2pin_map = defaultdict(dict)

        # map (component, gate names) to annotation maps, dicts from
        # strings (name|value) to Annotations. These represent the
        # >NAME and >VALUE texts on eagle components, which must be
        # converted into component instance annotations since their
        # contents depend on the component instance name and value.
        self.cptgate2ann_map = defaultdict(dict)

        # map part names to component instances. These are used during
        # pinref processing in segments.
        self.part2inst = {}

        # map part names to gate names to symbol attributes. These
        # are used during pinref processing in segments.
        self.part2gate2symattr = defaultdict(dict)
 def test_units(self):
     """ Capture absence of units. """
     layout = Layout()
     layout.units = None
     layout.layers.append(Layer())
     design = Design()
     design.layout = layout
     writer = Writer()
     writer.write(design)
    def test_write_header(self):
        """
        The write_header method produces the right string.
        """

        design = Design()
        design.design_attributes.metadata.updated_timestamp = 0
        writer = KiCAD()
        buf = StringIO()
        writer.write_header(buf, design)
        self.assertEqual(buf.getvalue()[:40], 'EESchema Schematic File Version 2  date ')
 def test_images(self):
     """ Capture images with no data. """
     layer = Layer()
     layer.images.append(Image())
     layout = Layout()
     layout.units = 'mm'
     layout.layers.append(layer)
     design = Design()
     design.layout = layout
     writer = Writer()
     writer.write(design)
    def parse(self, infile='.'):
        """ Parse tokens from gerber files into a design. """
        is_zip = infile.endswith('.zip')
        openarchive = ZipFile if is_zip else TarFile.open
        archive = batch_member = None
        try:
            # define multiple layers from folder
            if LAYERS_CFG in infile:
                archive = None
                cfg_name = infile
                cfg = open(cfg_name, 'r')

            # define multiple layers from archivea
            else:
                archive = openarchive(infile)
                batch = archive.namelist if is_zip else archive.getnames
                batch_member = archive.open if is_zip else archive.extractfile
                cfg_name = [n for n in batch() if LAYERS_CFG in n][0]
                cfg = batch_member(cfg_name)

        # define single layer from single gerber file
        except ReadError:
            name, ext = path.split(infile)[1].rsplit('.', 1)
            layer_defs = [
                LayerDef(ext.lower() == 'ger' and name or ext, 'unknown',
                         infile)
            ]
            self._gen_layers(layer_defs, None, None)

        # tidy up batch specs
        else:
            layer_defs = [
                LayerDef(rec[0], rec[1],
                         path.join(path.split(cfg_name)[0], rec[2]))
                for rec in csv.reader(cfg, skipinitialspace=True)
            ]
            cfg.close()
            self._gen_layers(layer_defs, archive, batch_member)

        # tidy up archive
        finally:
            if archive:
                archive.close()

        # compile design
        if DEBUG:
            self._debug_stdout()

        self.layout.units = (self.params['MO'] == 'IN' and 'inch' or 'mm')

        design = Design()
        design.layout = self.layout
        return design
    def parse(self, filename, library_filename=None):
        """ Parse a kicad file into a design """

        design = Design()
        segments = set()  # each wire segment
        junctions = set()  # wire junction point (connects all wires under it)

        if library_filename is None:
            library_filename = splitext(filename)[0] + '-cache.lib'
            if exists(library_filename):
                for cpt in parse_library(library_filename):
                    design.add_component(cpt.name, cpt)

        with open(filename) as f:
            libs = []
            line = f.readline().strip()

            # parse the library references
            while line and line != "$EndDescr":
                if line.startswith('LIBS:'):
                    libs.extend(line.split(':', 1)[1].split(','))
                line = f.readline().strip()

            # Now parse wires and components, ignore connections, we get
            # connectivity from wire segments

            line = f.readline()

            while line:
                prefix = line.split()[0]

                if line.startswith('Wire Wire Line'):
                    self.parse_wire(f, segments)
                elif prefix == "Connection":  # Store these to apply later
                    self.parse_connection(line, junctions)
                elif prefix == "Text":
                    design.design_attributes.add_annotation(
                        self.parse_text(f, line))
                elif prefix == "$Comp":  # Component Instance
                    inst = self.parse_component_instance(f)
                    design.add_component_instance(inst)
                    if inst.library_id not in design.components.components:
                        cpt = lookup_part(inst.library_id, libs)
                        if cpt is not None:
                            design.components.add_component(cpt.name, cpt)

                line = f.readline()

        segments = self.divide(segments, junctions)
        design.nets = self.calc_nets(segments)
        self.calc_connected_components(design)

        return design
Beispiel #9
0
 def test_generating_geda_commands_for_toplevel_shapes(self):
     design = Design()
     design.shapes = [
         shape.Line((0, 0), (0, 50)),
         shape.Circle(0, 0, 300),
     ]
     design.pins = [
         components.Pin('E', (0, 0), (0, 30)),
         components.Pin('E', (0, 0), (0, 30)),
     ]
     commands = self.geda_writer.generate_body_commands(design)
     ## default pins require 6 commands, shapes require 1 command
     self.assertEquals(len(commands), 2 * 6 + 2 * 1)
    def parse(self, filename):
        """ Parse a specctra file into a design """

        self.design = Design()

        with open(filename) as f:
            data = f.read()

        tree = DsnParser().parse(data)

        struct = self.walk(tree)
        self.resolution = struct.resolution
        self._convert(struct)

        return self.design
Beispiel #11
0
    def __init__(self):
        self.design = Design()

        # This maps fritzing connector keys to (x, y) coordinates
        self.points = {}  # (index, connid) -> (x, y)

        # This maps fritzing component indices to ComponentInstances
        self.component_instances = {}  # index -> ComponentInstance

        # Map connector keys to the list of connector keys they
        # are connected to.
        self.connects = {}  # (index, connid) -> [(index, connid)]

        self.components = {}  # idref -> ComponentParser

        self.fritzing_version = None
        self.fzz_zipfile = None  # The ZipFile if we are parsing an fzz
Beispiel #12
0
    def parse_schematic(self, stream):
        """ Parse a gEDA schematic provided as a *stream* object into a
            design.

            Returns the design corresponding to the schematic.
        """
        # pylint: disable=R0912
        if self.design is None:
            self.design = Design()

        self.segments = set()
        self.net_points = dict()
        self.net_names = dict()

        obj_type, params = self._parse_command(stream)

        while obj_type is not None:

            objects = getattr(self, "_parse_%s" % obj_type)(stream, params)

            attributes = self._parse_environment(stream)
            self.design.design_attributes.attributes.update(attributes or {})

            self.add_objects_to_design(self.design, objects)

            obj_type, params = self._parse_command(stream)

        ## process net segments into nets & net points and add to design
        self.divide_segments()

        calculated_nets = self.calculate_nets()

        for cnet in sorted(calculated_nets, key=lambda n: n.net_id):
            self.design.add_net(cnet)

        return self.design
def parse(eagle_obj):
    design = Design()
Beispiel #14
0
    def parse(self, inputfile):
        """ Parse a gEDA file into a design.

            Returns the design corresponding to the gEDA file.
        """
        inputfiles = []

        ## check if inputfile is in ZIP format
        if zipfile.is_zipfile(inputfile):
            self.geda_zip = zipfile.ZipFile(inputfile)
            for filename in self.geda_zip.namelist():
                if filename.endswith('.sch'):
                    inputfiles.append(filename)
        else:
            inputfiles = [inputfile]

        self.design = Design()

        ## parse frame data of first schematic to extract
        ## page size (assumes same frame for all files)
        with self._open_file_or_zip(inputfiles[0]) as stream:
            self._check_version(stream)

            for line in stream.readlines():
                if 'title' in line and line.startswith('C'):
                    obj_type, params = self._parse_command(StringIO(line))
                    assert (obj_type == 'C')

                    params['basename'], _ = os.path.splitext(
                        params['basename'], )

                    log.debug("using title file: %s", params['basename'])

                    self._parse_title_frame(params)

        ## store offset values in design attributes
        self.design.design_attributes.attributes.update({
            '_geda_offset_x':
            str(self.offset.x),
            '_geda_offset_y':
            str(self.offset.y),
            '_geda_frame_width':
            str(self.frame_width),
            '_geda_frame_height':
            str(self.frame_height),
        })

        for filename in inputfiles:
            f_in = self._open_file_or_zip(filename)
            self._check_version(f_in)

            self.parse_schematic(f_in)

            basename, _ = os.path.splitext(os.path.basename(filename))
            self.design.design_attributes.metadata.set_name(basename)

            ## modify offset for next page to be shifted to the right
            self.offset.x = self.offset.x - self.frame_width

            f_in.close()

        return self.design
 def test_layers(self):
     """ Capture absence of layers. """
     design = Design()
     design.layout = Layout()
     writer = Writer()
     writer.write(design)
 def test_layout(self):
     """ Capture absence of a layout. """
     design = Design()
     writer = Writer()
     writer.write(design)
 def __init__(self):
     self.design = Design()
Beispiel #18
0
 def setUp(self):
     """ Setup the test case. """
     self.des = Design()
Beispiel #19
0
    def parse(self, file_path):
        """ Parse an Altium file into a design """
        design = Design()

        # Open the file in read-binary mode and only proceed if it was properly opened.
        in_file = open(file_path, "rb")
        if in_file:
            # Read the entire contents, omitting the interrupting blocks.
            input = in_file.read(0x200)
            # Skip the first 0x200 interrupting block.
            temp = in_file.read(0x200)
            while temp:
                # Read the next 0x10000 minus 0x200.
                temp = in_file.read(0xFE00)
                input += temp
                # Skip the next 0x200 interrupting block.
                temp = in_file.read(0x200)
            in_file.close()
            # Store all the headers, though they are not used.
            cursor_start = 0
            self.first_header = input[cursor_start:cursor_start + 0x200]
            cursor_start += 0x200
            self.root_entry = input[cursor_start:cursor_start + 0x80]
            cursor_start += 0x80
            self.file_header = input[cursor_start:cursor_start + 0x80]
            cursor_start += 0x80
            self.storage = input[cursor_start:cursor_start + 0x80]
            cursor_start += 0x80
            self.additional = input[cursor_start:cursor_start + 0x80]
            cursor_start += 0x80
            self.last_header = input[cursor_start:cursor_start + 0x200]
            cursor_start += 0x200
            # Now prepare to read each of the parts.  Initialize an "end" cursor.
            cursor_end = 0
            # Get the size of the next part block.
            next_size = struct.unpack("<I",
                                      input[cursor_start:cursor_start + 4])[0]
            # Advance the "start" cursor.
            cursor_start += 4
            # Create a list to store all the parts.
            self.parts = []
            # Loop through until the "next size" is 0, which is the end of the parts list.
            while next_size != 0:
                cursor_end = input.find("\x00", cursor_start)
                # Create a dictionary to store all the property:value pairs.
                result = {}
                # Get a list of pairs by splitting on the separator character "|".
                property_list = input[cursor_start:cursor_end].split("|")
                # For each one, copy out whatever is before any "=" as property, and whatever is
                # after any "=" as value.
                for prop in property_list:
                    if prop:
                        property_val = p.split("=")[0]
                        # The negative list index is to handle the cases with "==" instead of "=".
                        value = p.split("=")[-1]
                        # Add the property to the result dictionary.
                        result[property_val] = value
                # Add the dictionary to the list of parts.
                self.parts.append(result)
                # Set things up for the next iteration of the loop.
                cursor_start = cursor_end + 1
                next_size = struct.unpack(
                    "<I", input[cursor_start:cursor_start + 4])[0]
                cursor_start += 4
            # Here the footers could be found and stored, but I don't think they're important.

        return design
    def __init__(self):
        self.design = Design()

        # map components to gate names to symbol indices
        self.cpt2gate2symbol_index = defaultdict(dict)