Generator.py

Go to the documentation of this file.
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 ##@package grc_gnuradio.Generator
00020 #Create python based flow graphs.
00021 #@author Josh Blum
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                 #generate
00054                 open(self.get_file_path(), 'w').write(str(self))
00055                 if self._generate_options == 'hb':
00056                         #convert hier block to xml wrapper
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                 #execute
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                 #list of blocks not including variables and imports and parameters and disabled
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                 #list of connections where each endpoint is enabled
00084                 connections = self._flow_graph.get_enabled_connections()
00085                 #list of variable names
00086                 var_ids = [var.get_id() for var in parameters + variables]
00087                 #list of callbacks (prepend self.)
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                 #map var id to the expression (prepend self.)
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                 #create graph structure for variables
00098                 variable_graph = expr_utils.get_graph(var_id2expr)
00099                 #map var id to direct dependents
00100                 #for each var id, make a list of all 2nd order edges
00101                 #use all edges of that id that are not also 2nd order edges
00102                 #meaning: list variables the ONLY depend directly on this variable
00103                 #and not variables that also depend indirectly on this variable
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                 #map var id to callbacks
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                 #load the namespace
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                 #build the template
00130                 t = Template(open(FLOW_GRAPH_TEMPLATE, 'r').read(), namespace)
00131                 return str(t)
00132 

Generated on Sat Aug 23 02:00:11 2008 for GNU Radio Companion by  doxygen 1.5.4