added include <cstdio> statements in several files to make it compatible with g+...
[debian/gnuradio] / grc / src / platforms / python / 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
20 from .. base.Block import Block as _Block
21 from utils import extract_docs
22
23 class Block(_Block):
24
25         ##for make source to keep track of indexes
26         _source_count = 0
27         ##for make sink to keep track of indexes
28         _sink_count = 0
29
30         def __init__(self, flow_graph, n):
31                 """
32                 Make a new block from nested data.
33                 @param flow graph the parent element
34                 @param n the nested odict
35                 @return block a new block
36                 """
37                 #grab the data
38                 doc = n.find('doc') or ''
39                 imports = map(lambda i: i.strip(), n.findall('import'))
40                 make = n.find('make')
41                 checks = n.findall('check')
42                 callbacks = n.findall('callback')
43                 #build the block
44                 _Block.__init__(
45                         self,
46                         flow_graph=flow_graph,
47                         n=n,
48                 )
49                 self._doc = doc
50                 self._imports = imports
51                 self._make = make
52                 self._callbacks = callbacks
53                 self._checks = checks
54
55         def validate(self):
56                 """
57                 Validate this block.
58                 Call the base class validate.
59                 Evaluate the checks: each check must evaluate to True.
60                 Adjust the nports.
61                 """
62                 _Block.validate(self)
63                 #evaluate the checks
64                 for check in self._checks:
65                         check_res = self.resolve_dependencies(check)
66                         try:
67                                 check_eval = self.get_parent().evaluate(check_res)
68                                 try: assert check_eval
69                                 except AssertionError: self._add_error_message('Check "%s" failed.'%check)
70                         except: self._add_error_message('Check "%s" did not evaluate.'%check)
71                 #adjust nports
72                 for ports, Port in (
73                         (self._sources, self.get_parent().get_parent().Source),
74                         (self._sinks, self.get_parent().get_parent().Sink),
75                 ):
76                         #how many ports?
77                         num_ports = len(ports)
78                         #do nothing for 0 ports
79                         if not num_ports: continue
80                         #get the nports setting
81                         port0 = ports[str(0)]
82                         nports = port0.get_nports()
83                         #do nothing for no nports
84                         if not nports: continue
85                         #do nothing if nports is already num ports
86                         if nports == num_ports: continue
87                         #remove excess ports and connections
88                         if nports < num_ports:
89                                 #remove the connections
90                                 for key in map(str, range(nports, num_ports)):
91                                         port = ports[key]
92                                         for connection in port.get_connections():
93                                                 self.get_parent().remove_element(connection)
94                                 #remove the ports
95                                 for key in map(str, range(nports, num_ports)): ports.pop(key)
96                                 continue
97                         #add more ports
98                         if nports > num_ports:
99                                 for key in map(str, range(num_ports, nports)):
100                                         n = port0._n
101                                         n['key'] = key
102                                         port = Port(self, n)
103                                         ports[key] = port
104                                 continue
105
106         def port_controller_modify(self, direction):
107                 """
108                 Change the port controller.
109                 @param direction +1 or -1
110                 @return true for change
111                 """
112                 changed = False
113                 #concat the nports string from the private nports settings of both port0
114                 nports_str = \
115                         (self.get_sinks() and self.get_sinks()[0]._nports or '') + \
116                         (self.get_sources() and self.get_sources()[0]._nports or '')
117                 #modify all params whose keys appear in the nports string
118                 for param in self.get_params():
119                         if param.is_enum() or param.get_key() not in nports_str: continue
120                         #try to increment the port controller by direction
121                         try:
122                                 value = param.evaluate()
123                                 value = value + direction
124                                 assert 0 < value
125                                 param.set_value(value)
126                                 changed = True
127                         except: pass
128                 return changed
129
130         def get_doc(self):
131                 doc = self._doc.strip('\n').replace('\\\n', '')
132                 #merge custom doc with doxygen docs
133                 return '\n'.join([doc, extract_docs.extract(self.get_key())]).strip('\n')
134
135         def get_imports(self):
136                 """
137                 Resolve all import statements.
138                 Split each import statement at newlines.
139                 Combine all import statments into a list.
140                 Filter empty imports.
141                 @return a list of import statements
142                 """
143                 return filter(lambda i: i, sum(map(lambda i: self.resolve_dependencies(i).split('\n'), self._imports), []))
144
145         def get_make(self): return self.resolve_dependencies(self._make)
146
147         def get_callbacks(self):
148                 """
149                 Get a list of function callbacks for this block.
150                 @return a list of strings
151                 """
152                 return map(lambda c: self.get_id() + '.' + self.resolve_dependencies(c), self._callbacks)