Xorn
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
pp_slotting.py
Go to the documentation of this file.
1 # xorn.geda.netlist - gEDA Netlist Extraction and Generation
2 # Copyright (C) 1998-2010 Ales Hvezda
3 # Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
4 # Copyright (C) 2013-2016 Roland Lutz
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software Foundation,
18 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 ## \namespace xorn.geda.netlist.pp_slotting
21 ## Post-processing: Slotting mechanism.
22 
23 from gettext import gettext as _
24 import xorn.geda.attrib
25 
26 ## Characters used to separate the pin labels in a \c "slotdef=" attribute.
27 SLOTDEF_ATTRIB_DELIMITERS = ',; '
28 
29 ## Split a string into non-empty parts separated by a set of delimiters.
30 
31 def strtok(s, delim):
32  start = 0
33  while start < len(s):
34  found = [i for i in (s.find(d, start) for d in delim) if i != -1]
35  if found:
36  end = min(found)
37  else:
38  end = len(s)
39  if end != start:
40  yield s[start:end]
41  start = end + 1
42 
43 ## Get the active slot definition of a component.
44 #
45 # Reads the \c "slotdef=" and \c "slot=" attributes of the component
46 # and returns the appropriate slot definition for the slot, parsed
47 # into a list of pin labels. If the component isn't slotted or the
48 # slotting attributes are invalid, returns \c None.
49 
50 def get_slotdef(component_blueprint):
51  # For this particular graphic object (component instantiation)
52  # get the slot number as a string
53 
54  try:
55  value = component_blueprint.get_attribute('slot')
56  except KeyError:
57  # Did not find slot= attribute.
58  # This happens if there is no attached slot attribute, and
59  # there is no default slot= attribute inside the symbol.
60  # Assume slot=1.
61  slot = 1
62  slot_string = False
63  else:
64  try:
65  slot = int(value)
66  except ValueError:
67  component_blueprint.error(
68  _("non-numeric slot= attribute: %s") % value)
69  slot = 0
70  slot_string = True
71 
72  # OK, now that we have the slot number, use it to get the
73  # corresponding slotdef=#:#,#,# string.
74  slotdef = None
75  for value in xorn.geda.attrib.search_all(
76  component_blueprint.ob, 'slotdef'):
77  if ':' not in value:
78  # Didn't find proper slotdef=#:... put warning into log
79  component_blueprint.error(
80  _("improper slotdef= syntax: missing \":\" in \"%s\"") % value)
81  return None
82 
83  if value.startswith('%d:' % slot):
84  slotdef = value
85  break
86 
87  if slotdef is None:
88  if slot_string:
89  # only an error if there's a slot string
90  component_blueprint.error(
91  _("did not find slotdef= attribute for slot %d") % slot)
92  return None
93 
94  # skip over slotdef number
95  # slotdef is in the form #:#,#,#
96  # this code skips first #:
97  cptr = slotdef[slotdef.index(':') + 1:] # skip colon
98 
99  if not cptr:
100  component_blueprint.error(_("improper slotdef= syntax: "
101  "missing definition for slot %d") % slot)
102  return None
103 
104  return list(strtok(cptr, SLOTDEF_ATTRIB_DELIMITERS))
105 
106 def postproc_blueprints(netlist):
107  for schematic in netlist.schematics:
108  for component in schematic.components:
109  # parse the slotdef= and slot= attributes of the component
110  # and extract the effective list of pinnumbers for this slot
111  component.slotdef = get_slotdef(component)
112 
113  # create a dictionary of pins by pinseq
114  component.pins_by_pinseq = {}
115  for pin in component.pins:
116  try:
117  value = pin.get_attribute('pinseq')
118  except KeyError:
119  continue
120  try:
121  pinseq = int(value)
122  except ValueError:
123  pin.error(_("non-numeric pinseq value: %s") % value)
124  continue
125  if pinseq in component.pins_by_pinseq:
126  if component.slotdef \
127  and pinseq - 1 >= 0 \
128  and pinseq - 1 < len(component.slotdef):
129  pin.error(_("duplicate pinseq \"%s\"") % pinseq)
130  else:
131  pin.warn(_("duplicate pinseq \"%s\"") % pinseq)
132  continue
133  component.pins_by_pinseq[pinseq] = pin
134  if component.slotdef is not None \
135  and pinseq - 1 >= len(component.slotdef):
136  pin.warn(_("pin has pinseq=%d, but only %d pins are "
137  "covered by slot definition") % (
138  pinseq, len(component.slotdef)))
139 
140  # for non-slotted components, just assign regular pinnumbers
141  for pin in component.pins:
142  pin.number = pin.get_attribute('pinnumber', None)
143 
144  # override these pinnumbers with the ones from the slot definition
145  if component.slotdef is not None:
146  for i, pinnumber in enumerate(component.slotdef):
147  try:
148  pin = component.pins_by_pinseq[i + 1]
149  except KeyError:
150  component.error(
151  _("slot definition covers %d pins, "
152  "but there is no pin with pinseq=%d") % (
153  len(component.slotdef), i + 1))
154  else:
155  pin.number = pinnumber
156 
157  # create a dictionary of pins by pinnumber
158  component.pins_by_number = {}
159  for pin in component.pins:
160  if pin.number is None:
161  pin.error(_("pinnumber missing"))
162  elif pin.number in component.pins_by_number:
163  if component.composite_sources:
164  pin.warn(_("duplicate pinnumber \"%s\"") % pin.number)
165  else:
166  pin.error(_("duplicate pinnumber \"%s\"") % pin.number)
167  else:
168  component.pins_by_number[pin.number] = pin
Attribute parsing and lookup.
Definition: attrib.py:1
def get_slotdef
Get the active slot definition of a component.
Definition: pp_slotting.py:50
def search_all
Search both attached and inherited attributes of a component for an attribute name and return matchin...
Definition: attrib.py:186
def strtok
Split a string into non-empty parts separated by a set of delimiters.
Definition: pp_slotting.py:31