00001 """
00002 Copyright 2008 Free Software Foundation, Inc.
00003 This file is part of GNU Radio
00004
00005 GNU Radio Companion is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009
00010 GNU Radio Companion is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 GNU General Public License for more details.
00014
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00018 """
00019
00020
00021
00022
00023 from utils import expr_utils
00024 from grc.elements.Param import Param as _Param
00025 import os
00026
00027 class Param(_Param):
00028
00029 _init = False
00030 _hostage_cells = list()
00031
00032
00033 TYPES = _Param.TYPES + [
00034 'complex', 'real', 'int',
00035 'complex_vector', 'real_vector', 'int_vector',
00036 'hex', 'string',
00037 'file_open', 'file_save',
00038 'id',
00039 'grid_pos', 'import',
00040 ]
00041
00042 def get_hide(self):
00043 """!
00044 Get the hide value from the base class.
00045 If hide was empty, and this is a type controller, set hide to part.
00046 If hide was empty, and this is an id of a non variable, set hide to part.
00047 @return hide the hide property string
00048 """
00049 hide = _Param.get_hide(self)
00050
00051 if not hide and self.get_key() in (
00052 'type', 'vlen', 'num_inputs', 'num_outputs'
00053 ): hide = 'part'
00054
00055 elif not hide and self.get_key() == 'id' and self.get_parent().get_key() not in (
00056 'variable', 'variable_slider', 'variable_chooser', 'variable_text_box', 'parameter', 'options'
00057 ): hide = 'part'
00058 return hide
00059
00060 def evaluate(self):
00061 """!
00062 Evaluate the value.
00063 @return evaluated type
00064 """
00065 self._lisitify_flag = False
00066 self._stringify_flag = False
00067 self._hostage_cells = list()
00068 def eval_string(v):
00069 try:
00070 e = self.get_parent().get_parent().evaluate(v)
00071 assert(isinstance(e, str))
00072 return e
00073 except:
00074 self._stringify_flag = True
00075 return v
00076 t = self.get_type()
00077 v = self.get_value()
00078
00079
00080
00081 if self.is_enum(): return self.get_value()
00082
00083
00084
00085 elif t in ('raw', 'complex', 'real', 'int', 'complex_vector', 'real_vector', 'int_vector', 'hex'):
00086
00087 try: e = self.get_parent().get_parent().evaluate(v)
00088 except:
00089 self._add_error_message('Value "%s" cannot be evaluated.'%v)
00090 raise Exception
00091
00092 if t == 'raw': return e
00093 elif t == 'complex':
00094 try: assert(isinstance(e, (complex, float, int, long)))
00095 except AssertionError:
00096 self._add_error_message('Expression "%s" is invalid for type complex.'%str(e))
00097 raise Exception
00098 return e
00099 elif t == 'real':
00100 try: assert(isinstance(e, (float, int, long)))
00101 except AssertionError:
00102 self._add_error_message('Expression "%s" is invalid for type real.'%str(e))
00103 raise Exception
00104 return e
00105 elif t == 'int':
00106 try: assert(isinstance(e, (int, long)))
00107 except AssertionError:
00108 self._add_error_message('Expression "%s" is invalid for type integer.'%str(e))
00109 raise Exception
00110 return e
00111 elif t == 'complex_vector':
00112 if not isinstance(e, (tuple, list, set)):
00113 self._lisitify_flag = True
00114 e = [e]
00115 try:
00116 for ei in e:
00117 assert(isinstance(ei, (complex, float, int, long)))
00118 except AssertionError:
00119 self._add_error_message('Expression "%s" is invalid for type complex vector.'%str(e))
00120 raise Exception
00121 return e
00122 elif t == 'real_vector':
00123 if not isinstance(e, (tuple, list, set)):
00124 self._lisitify_flag = True
00125 e = [e]
00126 try:
00127 for ei in e:
00128 assert(isinstance(ei, (float, int, long)))
00129 except AssertionError:
00130 self._add_error_message('Expression "%s" is invalid for type real vector.'%str(e))
00131 raise Exception
00132 return e
00133 elif t == 'int_vector':
00134 if not isinstance(e, (tuple, list, set)):
00135 self._lisitify_flag = True
00136 e = [e]
00137 try:
00138 for ei in e:
00139 assert(isinstance(ei, (int, long)))
00140 except AssertionError:
00141 self._add_error_message('Expression "%s" is invalid for type integer vector.'%str(e))
00142 raise Exception
00143 return e
00144 elif t == 'hex':
00145 return hex(e)
00146 else: raise TypeError, 'Type "%s" not handled'%t
00147
00148
00149
00150 elif t in ('string', 'file_open', 'file_save'):
00151
00152 e = eval_string(v)
00153 return str(e)
00154
00155
00156
00157 elif t == 'id':
00158
00159 try:
00160 assert(len(v) > 0)
00161 assert(v[0].isalpha())
00162 for c in v: assert(c.isalnum() or c in ('_',))
00163 except AssertionError:
00164 self._add_error_message('ID "%s" must be alpha-numeric or underscored, and begin with a letter.'%v)
00165 raise Exception
00166 params = self.get_all_params('id')
00167 keys = [param.get_value() for param in params]
00168 try: assert(len(keys) == len(set(keys)))
00169 except:
00170 self._add_error_message('ID "%s" is not unique.'%v)
00171 raise Exception
00172 return v
00173
00174
00175
00176 elif t == 'grid_pos':
00177 if not v: return ''
00178 e = self.get_parent().get_parent().evaluate(v)
00179 try:
00180 assert(isinstance(e, (list, tuple)) and len(e) == 4)
00181 for ei in e: assert(isinstance(ei, int))
00182 except AssertionError:
00183 self._add_error_message('A grid position must be a list of 4 integers.')
00184 raise Exception
00185 row, col, row_span, col_span = e
00186
00187 try: assert(row >= 0 and col >= 0)
00188 except AssertionError:
00189 self._add_error_message('Row and column must be non-negative.')
00190 raise Exception
00191
00192 try: assert(row_span > 0 and col_span > 0)
00193 except AssertionError:
00194 self._add_error_message('Row and column span must be greater than zero.')
00195 raise Exception
00196
00197 for r in range(row_span):
00198 for c in range(col_span):
00199 self._hostage_cells.append((row+r, col+c))
00200
00201 params = filter(lambda p: p is not self, self.get_all_params('grid_pos'))
00202 for param in params:
00203 for cell in param._hostage_cells:
00204 if cell in self._hostage_cells:
00205 self._add_error_message('Another graphical element is using cell "%s".'%str(cell))
00206 raise Exception
00207 return e
00208
00209
00210
00211 elif t == 'import':
00212 n = dict()
00213 try: exec v in n
00214 except ImportError:
00215 self._add_error_message('Import "%s" failed.'%v)
00216 raise Exception
00217 except Exception:
00218 self._add_error_message('Bad import syntax: "%s".'%v)
00219 raise Exception
00220 return filter(lambda k: str(k) != '__builtins__', n.keys())
00221
00222 else: raise TypeError, 'Type "%s" not handled'%t
00223
00224 def to_code(self):
00225 """!
00226 Convert the value to code.
00227 @return a string representing the code
00228 """
00229
00230 if not self._init:
00231 self.evaluate()
00232 self._init = True
00233 v = self.get_value()
00234 t = self.get_type()
00235 if t in ('string', 'file_open', 'file_save'):
00236 if self._stringify_flag:
00237 return '"%s"'%v.replace('"', '\"')
00238 else:
00239 return v
00240 elif t in ('complex_vector', 'real_vector', 'int_vector'):
00241 if self._lisitify_flag:
00242 return '(%s, )'%v
00243 else:
00244 return '(%s)'%v
00245 else:
00246 return v
00247
00248 def get_all_params(self, type):
00249 """!
00250 Get all the params from the flowgraph that have the given type.
00251 @param type the specified type
00252 @return a list of params
00253 """
00254 return sum([filter(lambda p: p.get_type() == type, block.get_params()) for block in self.get_parent().get_parent().get_blocks()], [])
00255