a14df8ec904b7ec3e29658f51d6e1cd2106affd3
[debian/gnuradio] / grc / src / grc_gnuradio / Block.py
1 """
2 Copyright 2008 Free Software Foundation, Inc.
3 This file is part of GNU Radio
4
5 GNU Radio Companion is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 GNU Radio Companion is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18 """
19 ##@package grc_gnuradio.Block
20 #Flow graph block.
21 #@author Josh Blum
22
23 from grc.elements.Block import Block as _Block
24 from grc import Utils
25 from utils import extract_docs
26
27 class Block(_Block):
28
29         ##for make source to keep track of indexes
30         _source_count = 0
31         ##for make sink to keep track of indexes
32         _sink_count = 0
33
34         def __init__(self, flow_graph, n):
35                 """
36                 Make a new block from nested data.
37                 @param flow graph the parent element
38                 @param n the nested odict
39                 @return block a new block
40                 """
41                 #grab the data
42                 doc = Utils.exists_or_else(n, 'doc', '')
43                 imports = map(lambda i: i.strip(), Utils.listify(n, 'import'))
44                 make = n['make']
45                 checks = Utils.listify(n, 'check')
46                 callbacks = Utils.listify(n, 'callback')
47                 #build the block
48                 _Block.__init__(
49                         self,
50                         flow_graph=flow_graph,
51                         n=n,
52                 )
53                 self._doc = doc
54                 self._imports = imports
55                 self._make = make
56                 self._callbacks = callbacks
57                 self._checks = checks
58
59         def validate(self):
60                 """!
61                 Validate this block.
62                 Call the base class validate.
63                 Evaluate the checks: each check must evaluate to True.
64                 Adjust the nports.
65                 """
66                 _Block.validate(self)
67                 #evaluate the checks
68                 for check in self._checks:
69                         check_res = self.resolve_dependencies(check)
70                         try:
71                                 check_eval = self.get_parent().evaluate(check_res)
72                                 try: assert check_eval
73                                 except AssertionError: self._add_error_message('Check "%s" failed.'%check)
74                         except: self._add_error_message('Check "%s" did not evaluate.'%check)
75                 for ports, Port in (
76                         (self._sources, self.get_parent().get_parent().Source),
77                         (self._sinks, self.get_parent().get_parent().Sink),
78                 ):
79                         #how many ports?
80                         num_ports = len(ports)
81                         #do nothing for 0 ports
82                         if not num_ports: continue
83                         #get the nports setting
84                         port0 = ports[str(0)]
85                         nports = port0.get_nports()
86                         #do nothing for no nports
87                         if not nports: continue
88                         #do nothing if nports is already num ports
89                         if nports == num_ports: continue
90                         #remove excess ports and connections
91                         if nports < num_ports:
92                                 #remove the connections
93                                 for key in map(str, range(nports, num_ports)):
94                                         port = ports[key]
95                                         for connection in port.get_connections():
96                                                 self.get_parent().remove_element(connection)
97                                 #remove the ports
98                                 for key in map(str, range(nports, num_ports)): ports.pop(key)
99                                 continue
100                         #add more ports
101                         if nports > num_ports:
102                                 for key in map(str, range(num_ports, nports)):
103                                         n = port0._n
104                                         n['key'] = key
105                                         port = Port(self, n)
106                                         ports[key] = port
107                                 continue
108
109         def get_doc(self):
110                 doc = self._doc.strip('\n').replace('\\\n', '')
111                 #merge custom doc with doxygen docs
112                 return '\n'.join([doc, extract_docs.extract(self.get_key())]).strip('\n')
113
114         def get_imports(self):
115                 """!
116                 Resolve all import statements.
117                 Split each import statement at newlines.
118                 Combine all import statments into a list.
119                 Filter empty imports.
120                 @return a list of import statements
121                 """
122                 return filter(lambda i: i, sum(map(lambda i: self.resolve_dependencies(i).split('\n'), self._imports), []))
123
124         def get_make(self): return self.resolve_dependencies(self._make)
125
126         def get_callbacks(self):
127                 """!
128                 Get a list of function callbacks for this block.
129                 @return a list of strings
130                 """
131                 return map(lambda c: self.get_id() + '.' + self.resolve_dependencies(c), self._callbacks)