Add additional conditionalization of networking includes
[debian/gnuradio] / grc / python / FlowGraph.py
1 """
2 Copyright 2008, 2009 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 import expr_utils
21 from .. base.FlowGraph import FlowGraph as _FlowGraph
22 from .. gui.FlowGraph import FlowGraph as _GUIFlowGraph
23 import re
24
25 _variable_matcher = re.compile('^(variable\w*)$')
26 _parameter_matcher = re.compile('^(parameter)$')
27
28 class FlowGraph(_FlowGraph, _GUIFlowGraph):
29
30         def __init__(self, **kwargs):
31                 _FlowGraph.__init__(self, **kwargs)
32                 _GUIFlowGraph.__init__(self)
33                 self._eval_cache = dict()
34
35         def _eval(self, code, namespace, namespace_hash):
36                 """
37                 Evaluate the code with the given namespace.
38                 @param code a string with python code
39                 @param namespace a dict representing the namespace
40                 @param namespace_hash a unique hash for the namespace
41                 @return the resultant object
42                 """
43                 if not code: raise Exception, 'Cannot evaluate empty statement.'
44                 my_hash = hash(code) ^ namespace_hash
45                 #cache if does not exist
46                 if not self._eval_cache.has_key(my_hash):
47                         self._eval_cache[my_hash] = eval(code, namespace, namespace)
48                 #return from cache
49                 return self._eval_cache[my_hash]
50
51         def _get_io_signaturev(self, pad_key):
52                 """
53                 Get a list of io signatures for this flow graph.
54                 The pad key determines the directionality of the io signature.
55                 @param pad_key a string of pad_source or pad_sink
56                 @return a list of dicts with: type, label, vlen, size
57                 """
58                 pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks())
59                 sorted_pads = sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id()))
60                 #load io signature
61                 return [{
62                         'label': str(pad.get_param('label').get_evaluated()),
63                         'type': str(pad.get_param('type').get_evaluated()),
64                         'vlen': str(pad.get_param('vlen').get_evaluated()),
65                         'size': pad.get_param('type').get_opt('size'),
66                 } for pad in sorted_pads]
67
68         def get_input_signaturev(self):
69                 """
70                 Get the io signature for the input side of this flow graph.
71                 @return a list of io signature structures
72                 """
73                 return self._get_io_signaturev('pad_source')
74
75         def get_output_signaturev(self):
76                 """
77                 Get the io signature for the output side of this flow graph.
78                 @return a list of io signature structures
79                 """
80                 return self._get_io_signaturev('pad_sink')
81
82         def get_imports(self):
83                 """
84                 Get a set of all import statments in this flow graph namespace.
85                 @return a set of import statements
86                 """
87                 imports = sum([block.get_imports() for block in self.get_enabled_blocks()], [])
88                 imports = sorted(set(imports))
89                 return imports
90
91         def get_variables(self):
92                 """
93                 Get a list of all variables in this flow graph namespace.
94                 Exclude paramterized variables.
95                 @return a sorted list of variable blocks in order of dependency (indep -> dep)
96                 """
97                 variables = filter(lambda b: _variable_matcher.match(b.get_key()), self.get_enabled_blocks())
98                 return expr_utils.sort_objects(variables, lambda v: v.get_id(), lambda v: v.get_var_make())
99
100         def get_parameters(self):
101                 """
102                 Get a list of all paramterized variables in this flow graph namespace.
103                 @return a list of paramterized variables
104                 """
105                 parameters = filter(lambda b: _parameter_matcher.match(b.get_key()), self.get_enabled_blocks())
106                 return parameters
107
108         def rewrite(self):
109                 """
110                 Flag the namespace to be renewed.
111                 """
112                 self._renew_eval_ns = True
113                 _FlowGraph.rewrite(self)
114
115         def evaluate(self, expr):
116                 """
117                 Evaluate the expression.
118                 @param expr the string expression
119                 @throw Exception bad expression
120                 @return the evaluated data
121                 """
122                 if self._renew_eval_ns:
123                         self._renew_eval_ns = False
124                         #reload namespace
125                         n = dict()
126                         #load imports
127                         for imp in self.get_imports():
128                                 try: exec imp in n
129                                 except: pass
130                         #load parameters
131                         np = dict()
132                         for parameter in self.get_parameters():
133                                 try:
134                                         e = eval(parameter.get_param('value').to_code(), n, n)
135                                         np[parameter.get_id()] = e
136                                 except: pass
137                         n.update(np) #merge param namespace
138                         #load variables
139                         for variable in self.get_variables():
140                                 try:
141                                         e = eval(variable.get_param('value').to_code(), n, n)
142                                         n[variable.get_id()] = e
143                                 except: pass
144                         #make namespace public
145                         self.n = n
146                         self.n_hash = hash(str(n))
147                 #evaluate
148                 e = self._eval(expr, self.n, self.n_hash)
149                 return e