Xorn
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
attrib.py
Go to the documentation of this file.
1 # xorn.geda - Python library for manipulating gEDA files
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.attrib
21 ## Attribute parsing and lookup.
22 #
23 # An attribute is a normal text object with a string that is delimited
24 # by an equals sign ("="). The part before the equals sign is called
25 # \a name and the part of the string behind the equals sign is called
26 # \a value. Attributes can either be floating (that is, not attached
27 # to any object) or attached to a net (including pins and buses) or
28 # component.
29 #
30 # \note If one of the parts is empty, the name ends with a space
31 # character, or the value starts with a space character, the
32 # text object is not recognized as an attribute.
33 #
34 # In addition to its attached attributes, a component inherits the
35 # attributes which live as toplevel un-attached attributes inside the
36 # \c prim_objs of its symbol.
37 
38 import xorn.storage
39 import xorn.proxy
40 
41 ## Raised when trying to parse a text object that is not recognized as
42 ## an attribute.
43 
44 class MalformedAttributeError(Exception):
45  pass
46 
47 ## Parse an attribute string of the form \c name=value into its name
48 ## and value parts.
49 #
50 # \throws MalformedAttributeError if the passed string is not a
51 # syntactically correct attribute string
52 #
53 # \return A pair <tt>(name, value)</tt>.
54 
55 def parse_string(string):
56  try:
57  ptr = string.index('=')
58  except ValueError:
59  raise MalformedAttributeError
60  if ptr == 0 or ptr == len(string) - 1:
61  raise MalformedAttributeError
62  if string[ptr - 1] == ' ' or string[ptr + 1] == ' ':
63  raise MalformedAttributeError
64 
65  return string[:ptr], string[ptr + 1:]
66 
67 ## Tell whether an object is a text object whose text constitutes a
68 ## valid attribute.
69 #
70 # \throw KeyError if the object doesn't exist
71 
72 def is_attribute(ob):
73  data = ob.data()
74  if not isinstance(data, xorn.storage.Text):
75  return False # not a text
76  try:
77  parse_string(data.text)
78  except MalformedAttributeError:
79  return False # not a valid attribute
80 
81  return True
82 
83 ## Returns the toplevel objects of a component's symbol.
84 #
85 # \throw KeyError if the object doesn't exist
86 # \throw ValueError if the object isn't a component
87 
89  data = ob.data()
90  if not isinstance(data, xorn.storage.Component):
91  raise ValueError
92  return xorn.proxy.RevisionProxy(data.symbol.prim_objs).toplevel_objects()
93 
94 ## Return all floating attributes in the given revision.
95 
97  return [ob for ob in rev.toplevel_objects() if is_attribute(ob)]
98 
99 ## Return the attributes directly attached to a net or component.
100 #
101 # \throw KeyError if the object doesn't exist
102 
104  return [attrib for attrib in ob.attached_objects() if is_attribute(attrib)]
105 
106 ## Return the attributes inherited by a component via its symbol.
107 #
108 # \throw KeyError if the object doesn't exist
109 # \throw ValueError if the object isn't a component
110 
112  return [attrib for attrib in inherited_objects(ob) if is_attribute(attrib)]
113 
114 ## Return all attributes, attached and inherited, of the specified
115 ## component.
116 #
117 # This function aggregates the attached and inherited attributes
118 # belonging to a given object.
119 #
120 # \throw KeyError if the object doesn't exist
121 # \throw ValueError if the object isn't a component
122 
124  return [attrib for attrib in ob.attached_objects() + inherited_objects(ob)
125  if is_attribute(attrib)]
126 
127 
128 ## Search a list of objects for attributes with a certain name and
129 ## return their values.
130 #
131 # \return List of strings with the values of the matching attributes.
132 
133 def search(attribs, name):
134  found = []
135  for attrib in attribs:
136  data = attrib.data()
137  if not isinstance(data, xorn.storage.Text):
138  continue
139  try:
140  attrib_name, attrib_value = parse_string(data.text)
141  except MalformedAttributeError:
142  continue
143  if attrib_name == name:
144  found += [attrib_value]
145  return found
146 
147 ## Search the floating attributes in a revision for an attribute name
148 ## and return matching values.
149 #
150 # \return List of strings with the values of the matching attributes.
151 
152 def search_floating(rev, name):
153  return search(rev.toplevel_objects(), name)
154 
155 ## Search attributes attached to a net or component for an attribute
156 ## name and return matching values.
157 #
158 # \throw KeyError if the object doesn't exist
159 #
160 # \return List of strings with the values of the matching attributes.
161 
162 def search_attached(ob, name):
163  return search(ob.attached_objects(), name)
164 
165 ## Search attributes inherited by a component for an attribute name
166 ## and return matching values.
167 #
168 # \throw KeyError if the object doesn't exist
169 # \throw ValueError if the object isn't a component
170 #
171 # \return List of strings with the values of the matching attributes.
172 
173 def search_inherited(ob, name):
174  return search(inherited_objects(ob), name)
175 
176 ## Search both attached and inherited attributes of a component for an
177 ## attribute name and return matching values.
178 #
179 # For nets, use \ref search_attached instead.
180 #
181 # \throw KeyError if the object doesn't exist
182 # \throw ValueError if the object isn't a component
183 #
184 # \return List of strings with the values of the matching attributes.
185 
186 def search_all(ob, name):
187  return search(ob.attached_objects() + inherited_objects(ob), name)
188 
189 
190 ## Return all pins in a component with a particular attribute.
191 #
192 # \throw KeyError if \a ob doesn't exist
193 # \throw ValueError if \a ob isn't a component
194 #
195 # \return A list of pins with the given attribute.
196 
197 def find_pins_by_attribute(ob, name, value):
198  found = []
199  for pin in inherited_objects(ob):
200  data = pin.data()
201  if isinstance(data, xorn.storage.Net) and data.is_pin and \
202  value in search_attached(pin, name):
203  found += [pin]
204  return found
Raised when trying to parse a text object that is not recognized as an attribute. ...
Definition: attrib.py:44
Schematic net segment, bus segment, or pin.
Definition: storage.py:549
def search_floating
Search the floating attributes in a revision for an attribute name and return matching values...
Definition: attrib.py:152
def find_attached_attribs
Return the attributes directly attached to a net or component.
Definition: attrib.py:103
High-level revision proxy class.
Definition: proxy.py:24
def search_all
Search both attached and inherited attributes of a component for an attribute name and return matchin...
Definition: attrib.py:186
def search
Search a list of objects for attributes with a certain name and return their values.
Definition: attrib.py:133
def find_inherited_attribs
Return the attributes inherited by a component via its symbol.
Definition: attrib.py:111
def find_all_attribs
Return all attributes, attached and inherited, of the specified component.
Definition: attrib.py:123
def search_inherited
Search attributes inherited by a component for an attribute name and return matching values...
Definition: attrib.py:173
def inherited_objects
Returns the toplevel objects of a component's symbol.
Definition: attrib.py:88
def is_attribute
Tell whether an object is a text object whose text constitutes a valid attribute. ...
Definition: attrib.py:72
Schematic component.
Definition: storage.py:527
def search_attached
Search attributes attached to a net or component for an attribute name and return matching values...
Definition: attrib.py:162
Schematic text or attribute.
Definition: storage.py:583
High-level proxy classes for the storage backend.
Definition: proxy.py:1
def find_pins_by_attribute
Return all pins in a component with a particular attribute.
Definition: attrib.py:197
def find_floating_attribs
Return all floating attributes in the given revision.
Definition: attrib.py:96
Xorn storage backend.
Definition: storage.py:1
def parse_string
Parse an attribute string of the form name=value into its name and value parts.
Definition: attrib.py:55