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 import os
00024 import subprocess
00025 from Cheetah.Template import Template
00026 from utils import expr_utils
00027 from Constants import *
00028 from utils import convert_hier
00029
00030 class Generator(object):
00031
00032 def __init__(self, flow_graph, file_path):
00033 """!
00034 Initialize the generator object.
00035 Determine the file to generate.
00036 @param flow_graph the flow graph object
00037 @param file_path the path to write the file to
00038 """
00039 self._flow_graph = flow_graph
00040 self._generate_options = self._flow_graph.get_option('generate_options')
00041 if self._generate_options == 'hb':
00042 self._mode = HIER_BLOCK_FILE_MODE
00043 dirname = HIER_BLOCKS_LIB_PATH
00044 else:
00045 self._mode = TOP_BLOCK_FILE_MODE
00046 dirname = os.path.dirname(file_path)
00047 filename = self._flow_graph.get_option('id') + '.py'
00048 self._file_path = os.path.join(dirname, filename)
00049
00050 def get_file_path(self): return self._file_path
00051
00052 def write(self):
00053
00054 open(self.get_file_path(), 'w').write(str(self))
00055 if self._generate_options == 'hb':
00056
00057 convert_hier.convert_hier(self._flow_graph, self.get_file_path())
00058 os.chmod(self.get_file_path(), self._mode)
00059
00060 def get_popen(self):
00061 """!
00062 Execute this python flow graph.
00063 @return a popen object
00064 """
00065
00066 cmds = [PYEXEC, self.get_file_path()]
00067 if self._generate_options == 'no_gui':
00068 cmds = ['xterm', '-e'] + cmds
00069 p = subprocess.Popen(args=cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=False, universal_newlines=True)
00070 return p
00071
00072 def __str__(self):
00073 """!
00074 Convert the flow graph to python code.
00075 @return a string of python code
00076 """
00077 imports = self._flow_graph.get_imports()
00078 variables = self._flow_graph.get_variables()
00079 parameters = self._flow_graph.get_parameters()
00080
00081 blocks = sorted(self._flow_graph.get_enabled_blocks(), lambda x, y: cmp(x.get_id(), y.get_id()))
00082 blocks = filter(lambda b: b not in (imports + parameters + variables), blocks)
00083
00084 connections = self._flow_graph.get_enabled_connections()
00085
00086 var_ids = [var.get_id() for var in parameters + variables]
00087
00088 callbacks = [
00089 expr_utils.expr_prepend(cb, var_ids, 'self.')
00090 for cb in sum([block.get_callbacks() for block in self._flow_graph.get_blocks()], [])
00091 ]
00092
00093 var_id2expr = dict(
00094 [(var.get_id(), expr_utils.expr_prepend(var.get_make().split('\n')[0], var_ids, 'self.'))
00095 for var in parameters + variables]
00096 )
00097
00098 variable_graph = expr_utils.get_graph(var_id2expr)
00099
00100
00101
00102
00103
00104 var_id2deps = dict(
00105 [(var_id, filter(lambda e: e not in sum([list(variable_graph.get_edges(edge))
00106 for edge in variable_graph.get_edges(var_id)], []), variable_graph.get_edges(var_id)
00107 )
00108 )
00109 for var_id in var_ids]
00110 )
00111
00112 var_id2cbs = dict(
00113 [(var_id, filter(lambda c: var_id in expr_utils.expr_split(c), callbacks))
00114 for var_id in var_ids]
00115 )
00116
00117 namespace = {
00118 'imports': imports,
00119 'flow_graph': self._flow_graph,
00120 'variables': variables,
00121 'parameters': parameters,
00122 'blocks': blocks,
00123 'connections': connections,
00124 'generate_options': self._generate_options,
00125 'var_id2expr': var_id2expr,
00126 'var_id2deps': var_id2deps,
00127 'var_id2cbs': var_id2cbs,
00128 }
00129
00130 t = Template(open(FLOW_GRAPH_TEMPLATE, 'r').read(), namespace)
00131 return str(t)
00132